Blazor Server – 无法读取 null 的属性(读取 addEventListener)

huangapple go评论70阅读模式
英文:

Blazor Server - Cannot read properties of null (reading addEventListener)

问题

以下是您要翻译的部分:

In Blazor Server, I've created a div and made it essentially the size of my page; I want to test that, through an event listener in my javascript file, I can send an alert when the div is clicked. I've added my js file link in _Layout.cshtml:

My javascript file:
And on my Blazor component, I have my div with height, width, etc. on a StyleSheet.css file:

Blazor Component:
StyleSheet.css:
But when running my page, I'm getting the following error, pointed right at my event listener:

Cannot read properties of null (reading addEventListener).

My first thought was that the javascript file was being loaded too late, but now I'm not sure; maybe there is an error in my syntax somewhere? I've checked my ID on the component side and it seems to match what I have in the javascript, so I'm not really sure why my code is returning null for that ID.

UPDATE:

Per sschwei1, I added the following code and while the null error is gone, the alert does not seem to be triggered at all.

英文:

In Blazor Server, I've created a div and made it essentially the size of my page; I want to test that, through an event listener in my javascript file, I can send an alert when the div is clicked. I've added my js file link in _Layout.cshtml:

<head>
    <!-- Other code -->
    <script src="~/js/common.js"></script>
    <link href="css/StyleSheet.css" rel="stylesheet" />
</head>

My javascript file:

document.getElementById('scanner-page').addEventListener('click', touchHandler, true);

function touchHandler(e) {
    if (e.type == "click") {
        alert("You clicked!");
    }
}

And on my Blazor component, I have my div with height, width, etc. on a StyleSheet.css file:

Blazor Component:

<div id="scanner-page">
    <!-- Other code here -->
</div>

StyleSheet.css:

#scanner-page {
    height: 100%;
    width: 100%;
    margin:0;
    padding:0;
    overflow: auto;
}

But when running my page, I'm getting the following error, pointed right at my event listener:

> Cannot read properties of null (reading addEventListener).

My first thought was that the javascript file was being loaded too late, but now I'm not sure; maybe there is an error in my syntax somewhere? I've checked my ID on the component side and it seems to match what I have in the javascript, so I'm not really sure why my code is returning null for that ID.

UPDATE:

Per sschwei1, I added the following code and while the null error is gone, the alert does not seem to be triggered at all.

document.onload = function () {
    document.getElementById('scanner-page').addEventListener('click', touchHandler, true);
}

function touchHandler(e) {
    if (e.type == "click") {
        alert("You clicked!");
    }
}

答案1

得分: 1

你目前的问题是将事件分配给 div 的生命周期,即它在 DOM 中的存在。

您可以从 OnAfterRender 中调用一个 JsFunction 来在元素存在时分配处理程序。

但有一个更简单的方法:直接在组件中设置 onclick 事件。我已经在 MainLayout 中分配了它,以便它可以捕获页面上的任何位置的点击。

一旦捕获,您可以做任何您想做的事情。我只是做了一个类似于您的简单的 JsInterop 操作,可以在一个页面演示中使用,以保持简单。

MainLayout.razor

@inherits LayoutComponentBase
@inject IJSRuntime js;
<PageTitle>SO75438382</PageTitle>

<div class="page" @onclick=this.PageClicked>
    <div class="sidebar">
        <NavMenu />
    </div>

    <main>
        <div class="top-row px-4">
            <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
        </div>

        <article class="content px-4">
            @Body
        </article>
    </main>
</div>

@code {

    private async Task PageClicked()
    {
        // 可以调用 C# 代码或调用一个 js 函数
        bool confirm = await js.InvokeAsync<bool>("confirm", "Hello");
    }
}

注意:在点击按钮和链接等元素时可能会出现传播问题。

英文:

You're current problem is timing the assignment of event to the lifecycle of the div, i.e. it's existence in the DOM.

You can call a JsFunction from OnAfterEnder to assign the handler when the element exists.

But there's a simpler way: set up the onclick event directly in the component. I've assigned it in MainLayout so it captures a click anywhere on the page.

Once captured, you can do whatever you want. I just do a simple bit of JsInterop similar to yours, that I can include in a one page demo to keep things simple.

MainLayout.razor

@inherits LayoutComponentBase
@inject IJSRuntime js;
&lt;PageTitle&gt;SO75438382&lt;/PageTitle&gt;

&lt;div class=&quot;page&quot; @onclick=this.PageClicked&gt;
    &lt;div class=&quot;sidebar&quot;&gt;
        &lt;NavMenu /&gt;
    &lt;/div&gt;

    &lt;main&gt;
        &lt;div class=&quot;top-row px-4&quot;&gt;
            &lt;a href=&quot;https://docs.microsoft.com/aspnet/&quot; target=&quot;_blank&quot;&gt;About&lt;/a&gt;
        &lt;/div&gt;

        &lt;article class=&quot;content px-4&quot;&gt;
            @Body
        &lt;/article&gt;
    &lt;/main&gt;
&lt;/div&gt;

@code {

    private async Task PageClicked()
    {
        // can call C# stuff or make a call to a js function
        bool confirm = await js.InvokeAsync&lt;bool&gt;(&quot;confirm&quot;, &quot;Hello&quot;);
    }
}

Note: There will be propagation issues with clicking on say buttons and links.

huangapple
  • 本文由 发表于 2023年2月14日 00:06:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75438382.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定