blazor js互操作未选择html元素

时间:2020-05-26 21:41:09

标签: blazor

我有一个简单的方法,应该选择页面上的一个复选框,然后相应地切换侧栏。

function toggleSidebar() {
  var cbx = document.getElementById("toggler-in-sidebar");
  console.log(cbx);                                      //this line display null.
  //console.log("Is checkbox checked: " + cbx.checked);
}

alert() console.log()可以使用,但是使用页面上的 getElementById()元素进行选择会返回

这是我的剃须刀页面

@inherits LayoutComponentBase
@inject IJSRuntime JSRuntime

<div class="wrapper">
  <div class="sidebar">
    <div class="sidebar__header">
        <div class="sidebar__header__logo">
            Logo
        </div>
        <div class="sidebar__header__toggler">
            <label for="toggler-in-sidebar" class="sidebar__toggler__label">&equiv;</label>
            <input type="checkbox" id="toggler-in-sidebar" class="sidebar__toggler__checkbox" />
        </div>
    </div>
    <div class="sidebar__content">
        Sidebar content
    </div>
 </div>
 <div class="content">
    <header class="header">
        Header
    </header>
    <div class="page">
        @Body
    </div>
  </div>
 </div>

 @code {
  protected override async Task OnInitializedAsync()
  {
    await JSRuntime.InvokeVoidAsync("toggleSidebar");
  }
 }

这是index.html页面中的参考

<body>
  <app>Loading...</app>

  <script src="_framework/blazor.webassembly.js"></script>
  <script src="js/toggle-sidebar.js"></script>
</body>

我想念什么吗?

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

这看起来很简单。在您的OnInitialized方法期间,不包含DOM,因为它尚不存在。您需要使用另一种生命周期方法OnAfterRenderAsync,它的工作是等待DOM呈现,因此它都可用,并且 THEN 会按ID为您的元素追踪元素互操作。因此,只需将您的@code更改为:

@code {
  protected override async Task OnAfterRenderAsync(bool firstRender)
  {
    await JSRuntime.InvokeVoidAsync("toggleSidebar");
  }
 }

这应该可以助您一臂之力,然后您还可以在OnAfterRenderAsync方法中使用if语句仅在首次渲染时执行JS,或者仅在不是首次渲染时执行JS,依此类推

希望这会有所帮助!

答案 1 :(得分:1)

在Blazor中,默认render-mode="ServerPrerendered"

组件的实际初始标记在服务器上得到解析,并向下发送到浏览器。

浏览器最初会看到预渲染的HTML,然后交互将取代。

在预渲染期间,没有浏览器,因此也没有JavaScript,因此您无法与JavaScript互操作。

如果您使用JSInterop,请确保在OnAfterRenderAsyncOnInit上调用OnParameterSet进行调用。

因为OnAfterRenderAsync在预渲染期间未运行。 在调用JSInterop时进行异步调用,然后只能与WebAssembly和Blazor服务器一起使用,因为在Blazor服务器的情况下,调用是通过网络进行的,因此必须是异步调用。

希望它可以澄清您对生命周期/流量的怀疑!