首页 > 解决方案 > Blazor 服务器 Microsoft.JSInterop.JSException:“值 'window.resizeListener' 不是函数

问题描述

我正在创建一个 Blazor Server 应用程序,并且我想使用 c# 代码对浏览器调整大小事件做出反应。因此,我正在关注本教程:https ://jakewaro.medium.com/detecting-browser-resize-in-server-side-blazor-apps-8d75bbab4d37

当我启动应用程序时,我得到了这个异常:

Microsoft.JSInterop.JSException: "The value 'window.resizeListener' is not a function.
Error: The value 'window.resizeListener' is not a function.
    at p (http://localhost:60096/_framework/blazor.server.js:8:31071)
    at http://localhost:60096/_framework/blazor.server.js:8:31614
    at new Promise (<anonymous>)
    at e.beginInvokeJSFromDotNet (http://localhost:60096/_framework/blazor.server.js:8:31587)
    at http://localhost:60096/_framework/blazor.server.js:1:20052
    at Array.forEach (<anonymous>)
    at e.invokeClientMethod (http://localhost:60096/_framework/blazor.server.js:1:20022)
    at e.processIncomingData (http://localhost:60096/_framework/blazor.server.js:1:18006)
    at e.connection.onreceive (http://localhost:60096/_framework/blazor.server.js:1:11091)
    at WebSocket.i.onmessage (http://localhost:60096/_framework/blazor.server.js:1:39007)"

在此命令处:等待 JS.InvokeAsync("resizeListener", DotNetObjectReference.Create(this));

我不确定,为什么这个方法调用 window.resizeListener 并且这个异常只发生在我第一次加载网站时。但是,当我重新加载页面时,代码不起作用。

以下是相关代码:

function resizeListener(dotnethelper) {
$(window).resize(() => {
    let browserHeight = $(window).innerHeight();
    let browserWidth = $(window).innerWidth();
    dotnethelper.invokeMethodAsync('SetBrowserDimensions', browserWidth, browserHeight).then(() => {
        // success, do nothing
    }).catch(error => {
        console.log("Error during browser resize: " + error);
    });
});
}

protected override void OnInitialized()
{
    // Init Browser service with Javascript runtime        
    Browser.Init(JS);
    Browser.Resize += UpdatedBrowserWidth;
}

protected void UpdatedBrowserWidth(object sender, int width)
{
    if (!bigWindowSize && width >= 1000)
    {
        bigWindowSize = true;
        base.StateHasChanged();
    }
    else if (bigWindowSize && width < 1000)
    {
        bigWindowSize = false;
        base.StateHasChanged();
    }
}

public class BrowserService
{
    private IJSRuntime JS = null;
    public event EventHandler<int> Resize;
    private int browserWidth;
    private int browserHeight;
    public async void Init(IJSRuntime js)
    {
        // enforce single invocation            
        if (JS == null)
        {
            this.JS = js;
            await JS.InvokeAsync<string>("resizeListener", DotNetObjectReference.Create(this));
        }
    }

    [JSInvokable]
    public void SetBrowserDimensions(int jsBrowserWidth, int jsBrowserHeight)
    {
        browserWidth = jsBrowserWidth;
        browserHeight = jsBrowserHeight;
        // For simplicity, we're just using the new width
        this.Resize?.Invoke(this, jsBrowserWidth);
    }
}

标签: blazorblazor-server-side

解决方案


我认为您使用了错误的生命周期方法。Blazor 服务器应用程序不允许在任何生命周期方法中使用 Javascript 函数,但 OnAfterRenderAsync 除外。这不会发生在 WebAssembly 应用程序中,因为它是在客户端上加载的。我不知道您如何呈现您的页面,但我假设您设置了“ServerPrerendered”选项,而不是“Server”。

在您的 _Host 文件中不会发生这种情况的原因是因为它总是作为预渲染文件发送给客户端,并且您显然在纯 cshtml 文件中没有任何生命周期方法。要解决此问题,您应仅在确定页面已呈现后才执行 javascript。

protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            // JS code here
        }
    }

推荐阅读