You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor如何实时持续获取当前浏览器窗口宽度并响应resize事件

Blazor 窗口宽度实时监听实现方案

核心实现逻辑为:将原本单次拉取宽度的模式,改为「JS监听resize事件 → 主动通知Blazor侧更新宽度值 → 触发组件重渲染」的推送模式,首先需要修正你现有代码的问题:你当前的JS代码中addEventListener返回值是事件监听ID,不是窗口宽度,所以根本无法拿到正确的宽度值。


分步实现代码

步骤1:调整JS代码

新增节流逻辑避免resize事件触发过于频繁,同时增加主动通知Blazor的回调逻辑:

let dotNetRef;
// 初始化监听,接收Blazor侧传入的DotNet引用
export function initResizeListener(dotNetReference) {
    dotNetRef = dotNetReference;
    // 首次加载先返回当前宽度
    sendWidthUpdate();
    // 注册resize监听,200ms节流可自行调整
    let resizeTimer;
    window.addEventListener("resize", () => {
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(sendWidthUpdate, 200);
    });
}

// 向Blazor侧推送最新宽度
function sendWidthUpdate() {
    dotNetRef?.invokeMethodAsync('UpdateWindowWidth', window.innerWidth);
}

步骤2:调整UtilityService代码

封装宽度变化事件供组件订阅:

public class UtilityService
{
    private IJSObjectReference _module;
    // 宽度变化通知事件,组件可订阅该事件获取更新
    public event Action<double> OnWindowWidthChanged;

    // 你原本的GetModule逻辑保持不变即可
    private async Task<IJSObjectReference> GetModule()
    {
        return _module ??= await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./你的JS文件路径.js");
    }

    // 初始化监听方法
    public async Task InitResizeListener(DotNetObjectReference<UtilityService> dotNetRef)
    {
        var module = await GetModule();
        await module.InvokeVoidAsync("initResizeListener", dotNetRef);
    }

    // 供JS侧调用的回调方法
    [JSInvokable]
    public void UpdateWindowWidth(double width)
    {
        OnWindowWidthChanged?.Invoke(width);
    }
}

需要先在Program.cs中注册服务:

builder.Services.AddScoped<UtilityService>();

步骤3:调整Razor组件代码

订阅宽度变化事件,收到更新后触发重渲染:

@inject UtilityService utilityService
@implements IAsyncDisposable

@* 你原本的宽度判断分支逻辑保持不变 *@
@if (width < 768)
{
    // 小屏布局代码
}
else
{
    // 大屏布局代码
}

@code {
    private double width;
    private DotNetObjectReference<UtilityService> _dotNetRef;

    protected override async Task OnInitializedAsync()
    {
        _dotNetRef = DotNetObjectReference.Create(utilityService);
        // 订阅宽度变化事件
        utilityService.OnWindowWidthChanged += UpdateWidth;
        // 初始化监听
        await utilityService.InitResizeListener(_dotNetRef);
    }

    private void UpdateWidth(double newWidth)
    {
        width = newWidth;
        // 通知组件状态更新,触发重渲染
        StateHasChanged();
    }

    // 销毁时释放资源避免内存泄漏
    public async ValueTask DisposeAsync()
    {
        utilityService.OnWindowWidthChanged -= UpdateWidth;
        _dotNetRef?.Dispose();
    }
}

注意事项

  • 若只有单个组件需要监听宽度变化,也可以直接在组件内创建DotNet引用,不需要通过UtilityService中转,逻辑完全一致
  • JS中的节流时长可根据业务需求调整,避免resize事件触发过于频繁导致性能损耗

内容的提问来源于stack exchange,提问作者Franco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 14:54:04