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

Blazor Server实现DOM元素尺寸监听的问题排查与解决

问题:Blazor中监听指定Div尺寸变化的实现与排障

本人不擅长Javascript与Blazor结合开发,此前借助谷歌及AI工具实现了浏览器尺寸变更时触发Blazor应用代码的事件监听器。现需为指定<div id="abc">实现相同的尺寸监听功能,以便组件设置像素单位的宽高。

Blazor组件代码

@inject DivSizeService dService

.. html ..


@code {
.. 
protected override async Task OnInitializedAsync()
{
    dService.OnDivSizeChanged += HandleDivSizeChanged;  
}

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {

        if (firstRender)
        {
            await dService.StartListeningForDivSizeChanges("abc");
            await UpdateDivSize();
        }
    }

    private async void HandleDivSizeChanged(object sender, DivSizeChangedEventArgs e)
    {
        if (e.ElementId == "abc")
        {
            await UpdateDivSize();
        }
    }

    async Task UpdateDivSize()
    {
        divSize = await dService.GetDivSize("abc");
        Style = "Width: " + (divSize.Width - 50).ToString() + "px; Height: " + 
            (divSize.Height - 50).ToString() + "px;";

        ChildComponent.Refresh // pseudocode
    }
}

DivSizeService服务代码

public class DivSizeService
{
    private readonly IJSRuntime _js;

    public event EventHandler<DivSizeChangedEventArgs> OnDivSizeChanged;

    public DivSizeService(IJSRuntime js)
    {
        _js = js;
    }

    public async Task<DivSize> GetDivSize(string elementId)
    {
        return await _js.InvokeAsync<DivSize>("getElementDimensions", elementId);
        //var dimensions = await _js.InvokeAsync<DivSize>("getDimensionsA");
        //return new DivSize { Width = dimensions.Width, Height = dimensions.Height };
    }

    public async Task StartListeningForDivSizeChanges(string elementId)
    {
        await _js.InvokeVoidAsync("registerResizeListener", elementId, DotNetObjectReference.Create(this)); // updated
    }

    [JSInvokable]
    public void HandleDivSizeChanged(string elementId, DivSize newSize)
    {
        OnDivSizeChanged?.Invoke(this, new DivSizeChangedEventArgs(elementId, newSize));
    }
}

public class DivSizeChangedEventArgs : EventArgs
{
    public string ElementId { get; }
    public DivSize NewSize { get; }

    public DivSizeChangedEventArgs(string elementId, DivSize newSize)
    {
        ElementId = elementId;
        NewSize = newSize;
    }
}

Javascript代码

window.getElementDimensions = function (elementId) {
    const element = document.getElementById(elementId);
    return {
        width: element ? element.offsetWidth : 0,
        height: element ? element.offsetHeight : 0
    };
};

window.registerResizeListener = (element, dotnetReference) => {
    const observer = new ResizeObserver(entries => {
        for (let entry of entries) {
            const rect = entry.contentRect;
            console.log(entry.contentRect);

            const size = {
                width: rect.width,
                height: rect.height
            };
            dotnetReference.invokeMethodAsync('DivSizeService.HandleDivSizeChanged', element, size);
        }
    });

    observer.observe(document.getElementById(element));
}

运行报错

Exception thrown: 'Microsoft.JSInterop.JSException' in System.Private.CoreLib.dll
Exception thrown: 'Microsoft.JSInterop.JSException' in System.Private.CoreLib.dll
Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer: Warning: Unhandled exception rendering component: Failed to execute 'observe' on 'ResizeObserver': parameter 1 is not of type 'Element'.
TypeError: Failed to execute 'observe' on 'ResizeObserver': parameter 1 is not of type 'Element'.

已知window.registerResizeListener中接收到的element为"abc",推测是参数传递方式有误,导致observer.observe(element)报错。


更新1:

调整后Javascript可识别<div id="abc">的尺寸变化,但出现新错误:

Uncaught Error Error: System.ArgumentException: The type 'DivSizeService' does not contain a public invokable method with [JSInvokableAttribute("DivSizeService.HandleDivSizeChanged")].


更新2:问题解决!

由于已向Javascript传递了dotNetReference(指向DivSizeService实例),无需在调用方法时添加类名前缀。将Javascript代码中的调用语句:

dotnetReference.invokeMethodAsync('DivSizeService.HandleDivSizeChanged', element, size);

修改为:

dotnetReference.invokeMethodAsync('HandleDivSizeChanged', element, size);

问题得以解决。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:43:13