Blazor OnClick 无法在带有 JS 事件处理程序的元素内部工作

Blazor OnClick is not working inside element with JS event handler

尝试使用鼠标 select 特定 HTML 元素内的多个元素,类似于用户在 Windows 资源管理器中 select 多个文件和文件夹的方式。 Tested several libraries。一般来说,它们可以工作,但棘手的部分是每个 selectable 元素内部都有一个复选框。

<div class="container">
  <div class="selectable"><input type="checkbox" /></div>
  <div class="selectable"><input type="checkbox" /></div>
  <div class="selectable"><input type="checkbox" /></div>
</div>

使用鼠标到 select 元素,每个库都将 mousedownmousemovemouseup 事件处理程序添加到 container,它仍然可以作为在下面的代码笔中显示,container 上的 mousedown 通常与复选框上的 click 共存。

https://codepen.io/artemiusgreat/pen/eYWzrQb

显然,Blazor 不是这种情况,因为我有与上面代码笔中相同的标记,相同的事件,但是一旦我使用 JS 互操作将 mousedown 事件添加到 containercontainer 内的所有复选框都停止工作。有或没有 onclick,复选框显示为死的且不可点击。

<!-- Checkbox outside of container works fine -->
<input type="checkbox" @onclick=@(e => SelectCollection(e)) />

<div class="container"> <!-- Inner checkboxes work only if container doesn't have "mousedown" handler -->

  <!-- Checkbox inside of container with Blazor "onclick" does NOT work -->
  <input type="checkbox" @onclick=@(e => SelectCollection(e)) />

  <!-- Checkbox inside of container does NOT work even if it doesn't have any handlers -->
  <input type="checkbox" />
  
</div>

为什么???

这是你的代码工作...我想它不适合你的主要原因是你正在使用 click 事件,但你应该使用 change 事件。

@page "/"


<!-- Checkbox outside of container works fine -->
<input type="checkbox"  @onchange="@((args) => SelectCollection(args))" />

<div class="container" @onmousedown="@(() => message2 = "Down with the mouse: " + count++.ToString())"> <!-- Inner checkboxes work only if container doesn't have "mousedown" handler -->

  <!-- Checkbox inside of container with Blazor "onclick" does NOT work -->
  <input type="checkbox" @onchange="@((args) => SelectCollection(args))" />

  <!-- Checkbox inside of container does NOT work even if it doesn't have any handlers -->
  <input type="checkbox" />
  
</div>


<p>@message</p>
<p>@message2</p>
@code
{
    private string message;
    private string message2;
    private int count;

    protected async Task SelectCollection(ChangeEventArgs args)
    {
        message = args.Value.ToString();
        await Task.Yield();
    }
}

Enet 的回答是正确的,但我将添加一个单独的答案来描述根本原因。

正如我在评论中提到的,每个鼠标选择脚本都必须创建一个显示所选区域的动态 DIV。出于某种原因,当我从放置复选框的位置开始选择时,蓝色区域在复选框检测到点击事件之前创建。因此,此动态 DIV 在鼠标事件到达复选框之前拦截所有鼠标事件。

为了解决此问题,当我为所选区域创建 DIV 时,我将 DIV 的起始位置增加了 10 个像素,因此如果鼠标单击发生在复选框顶部坐标 { x: 5, y: 20 },那么 DIV 的位置应该移动到 { x: 15, y: 30 }。在这种情况下,屏幕截图上的蓝色区域不会拦截鼠标事件,并且复选框会按预期工作。