Blazor通过JS Interop监听window.resize事件:先在JS端注册监听器并调用.NET方法,再在C#组件中定义OnResize回调更新状态并重渲染。

Blazor 本身不直接提供内置的 window.resize 事件绑定机制,但可以通过 JavaScript 互操作(JS Interop)监听浏览器窗口大小变化,并把尺寸数据传回 C# 组件。整个过程分三步:注册 JS 监听器、定义回调方法、在组件中更新状态。
Java Maven Common
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
下载
用 JS Interop 注册 resize 监听器
需要在 JavaScript 端设置一个监听函数,在窗口大小变化时调用 .NET 方法。推荐在 `_Host.cshtml` 或 `index.html` 的 `<script>` 中添加:
<pre class='brush:js;toolbar:false;'>window.blazorHelpers = {
registerResizeListener: (dotNetObjRef) => {
const handleResize = () => {
dotNetObjRef.invokeMethodAsync('OnResize',
window.innerWidth,
window.innerHeight);
};
window.addEventListener('resize', handleResize);
// 立即触发一次,确保初始尺寸正确
handleResize();
// 返回清理函数(可选,用于取消订阅)
return () => window.removeEventListener('resize', handleResize);
}
};</pre><H3>在 Blazor 组件中接收并响应尺寸变化
组件里需定义:
- 两个字段存宽高(如 `windowWidth`, `windowHeight`)
- 一个 `IDisposable` 引用(便于后续取消监听)
- `[JSInvokable]` 方法 `OnResize` 接收 JS 调用
- 调用 `StateHasChanged()` 触发重渲染
<pre class='brush:razor;toolbar:false;'>@page "/resize-demo"
@inject IJSRuntime JSRuntime
<p>当前宽度: @windowWidth</p>
<p>当前高度: @windowHeight</p>
<button @onclick="StartListening">开始监听</button>
<button @onclick="StopListening">停止监听</button>
@code {
private int windowWidth;
private int windowHeight;
private IDisposable? resizeListener;
private async Task StartListening()
{
if (resizeListener is null)
{
resizeListener = await JSRuntime.InvokeUnmarshalled<IDisposable>(
"blazorHelpers.registerResizeListener",
DotNetObjectReference.Create(this));
}
}
private void StopListening()
{
resizeListener?.Dispose();
resizeListener = null;
}
[JSInvokable]
public void OnResize(int width, int height)
{
windowWidth = width;
windowHeight = height;
StateHasChanged();
}
}</pre><H3>注意几个关键细节
- 不要用 `InvokeAsync` 调用 `registerResizeListener`,它返回的是 JS 函数,而 `InvokeUnmarshalled` 更适合这种无 Promise 的同步注册场景
- 初始尺寸必须手动触发一次(比如在 `handleResize()` 里),否则组件首次加载时宽高为 0
- `DotNetObjectReference.Create(this)` 需要手动 `Dispose()`,否则可能引发内存泄漏;建议在 `Dispose(bool)` 中也做清理
- 如果只是做响应式布局判断(比如区分手机/桌面),可在 `OnResize` 里加断点逻辑,例如:
<pre class='brush:csharp;toolbar:false;'>public bool IsMobile => windowWidth < 768;
public string DeviceClass => IsMobile ? "mobile" : "desktop";</pre><p>基本上就这些。不需要引入第三方包,纯原生 Blazor + JS 互操作就能稳定工作。</script>