使用 Blazor Server 时如何添加客户端 DOM javascript 事件处理程序?

How to add client DOM javascript event handler when using Blazor Server?

...是的,我知道...Blazor 服务器是服务端,我可以在服务器端使用我的 C# 代码处理 DOM 事件...添加纯客户端仍然有意义javascript 事件处理程序,令人惊讶的是它似乎是不可能的,因为 _framework/blazor.server.js 吞噬了它们...

以下是重现我正在做的事情的最简单的独立步骤。

  1. 使用VS 2019模板创建Blazor App,下一步选择Blazor Server App。
  2. 在Index.razor任意位置加一行<div id="test">Hello, click me!</div>

  3. 在 _Host.cshtml 中,在已存在的 <script src="_framework/blazor.server.js"></script> 行之后或之前添加以下脚本:

    ...扯头发,代码块插入不了,这里,看第4步之后...

  4. 运行 应用程序,然后按 F12 以查看控制台输出。

这是第 3 步中的脚本:

<script>
    console.log("script is executing...");
    console.log("element found, its innerText is: " + document.getElementById("test").innerText);

    document.getElementById("test").addEventListener("click",
        function() {
            console.log("click handler called");
        });
</script>

问题

我错过了什么吗?是否可以在没有服务器往返的情况下完成这项工作?如果不可能,那么许多现有的 javascript 小部件和 jQuery 插件将如何初始化它们?

到目前为止我尝试了什么?

提前回答"why I would like to do this?":

例如,我想实现一个 DOM 行为,在该行为中单击某个元素会更改其属性中的某些内容。我知道,我可以附加一个 C# 处理程序,然后调用返回 javascript 函数,但我不喜欢这种往返。 除此之外,也许有许多现有的 javascript 插件和库依赖于其初始化脚本在 DOM.

上附加事件处理程序

...根据来自火星的 agua 在他的评论中指出的文档: (如果谁有更好的想法请回答或评论)

如果我 运行 我的客户端脚本附加了事件处理程序 服务器 OnAfterRender 事件之后,那么它就可以工作。如果我 运行 它之前以任何方式(例如在 OnInitialized 事件中)它将不起作用:

所以这是一个可行的解决方案: Index.razor

@code
{
    protected override void OnAfterRender(bool firstRender)
    {
        _jsRuntime.InvokeVoidAsync("attachHandlers");
    }
}

_Host.cshtml:

window.attachHandlers = () => {
    document.getElementById("test").addEventListener("click", function()
    {
         console.log("click handler called");
    });
};