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 元素,每个库都将 mousedown
、mousemove
、mouseup
事件处理程序添加到 container
,它仍然可以作为在下面的代码笔中显示,container
上的 mousedown
通常与复选框上的 click
共存。
https://codepen.io/artemiusgreat/pen/eYWzrQb
显然,Blazor 不是这种情况,因为我有与上面代码笔中相同的标记,相同的事件,但是一旦我使用 JS 互操作将 mousedown
事件添加到 container
,container
内的所有复选框都停止工作。有或没有 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 }
。在这种情况下,屏幕截图上的蓝色区域不会拦截鼠标事件,并且复选框会按预期工作。
尝试使用鼠标 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 元素,每个库都将 mousedown
、mousemove
、mouseup
事件处理程序添加到 container
,它仍然可以作为在下面的代码笔中显示,container
上的 mousedown
通常与复选框上的 click
共存。
https://codepen.io/artemiusgreat/pen/eYWzrQb
显然,Blazor 不是这种情况,因为我有与上面代码笔中相同的标记,相同的事件,但是一旦我使用 JS 互操作将 mousedown
事件添加到 container
,container
内的所有复选框都停止工作。有或没有 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 }
。在这种情况下,屏幕截图上的蓝色区域不会拦截鼠标事件,并且复选框会按预期工作。