我有一个简单的方法,应该选择页面上的一个复选框,然后相应地切换侧栏。
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">≡</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>
我想念什么吗?
感谢您的帮助。
答案 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,请确保在OnAfterRenderAsync
或OnInit
上调用OnParameterSet
并不进行调用。
因为OnAfterRenderAsync
在预渲染期间未运行。
在调用JSInterop时进行异步调用,然后只能与WebAssembly和Blazor服务器一起使用,因为在Blazor服务器的情况下,调用是通过网络进行的,因此必须是异步调用。
希望它可以澄清您对生命周期/流量的怀疑!