【问题标题】:Blazor OnClick is not working inside element with JS event handlerBlazor OnClick 在带有 JS 事件处理程序的元素内部不起作用
【发布时间】:2021-09-19 12:12:17
【问题描述】:

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

<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>

要使用鼠标选择元素,每个库都会在container 中添加mousedownmousemovemouseup 事件处理程序,它仍然可以正常工作,如下面的代码笔中所示,mousedowncontainer 上正常运行与复选框上的click 共存。

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

显然,Blazor 不是这种情况,因为我在上面的 codepen 中具有相同的标记,相同的事件,但是一旦我使用 JS 互操作将mousedown 事件添加到container,@987654335 中的所有复选框@ 停止工作。无论有没有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>

为什么???

【问题讨论】:

  • 我不是程序员,但我认为编程很容易。数百年前,还有一个人在喊“为什么???”,而他仍在等待答案。

标签: blazor blazor-server-side


【解决方案1】:

这是您的代码工作...我猜它对您不起作用的主要原因是您使用了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();
    }
}

【讨论】:

  • 感谢您的帮助,尽管您在作弊并从 Blazor 添加 mousedown,而不是从 JS。尽管如此,您的回答让我尝试了一些更简单的代码,我发现了真正的问题。当我开始拖动鼠标时,我在 HTML 中创建了一个动态 DIV,它反映了鼠标移动选择的区域。 This dynamic DIV is positioned on top of all other elements and when the selected area start on top of checkbox, it intercepts all clicks before they get to the checkbox.
  • 同时,这个问题在纯JS中是无法重现的。我可以在任何复选框上单击鼠标向下/向上,也可以按鼠标左键并开始向右移动选择红色框,因此 Blazor 本身可能仍然存在一些问题。 codepen.io/artemiusgreat/pen/eYWzrQb
  • 您认为enet 在“作弊”,因为他在使用。 . . Blazor 中的 Blazor 事件?那家伙的神经!
  • 谢谢你的好意,Bennyboy1973,但我不认为他有任何伤害......
【解决方案2】:

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

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多