javascript - Parent click handler is always executing first
问题描述
I have a simple list:
<li onClick={handleRowClick}>
<input type="checkbox" onClick={handleCheckboxClick} />
...
</li>
When I click in any place on the li
(except its checkbox child), handleRowClick
executes.
When I click on the checkbox
, it always executes in this order:
row
row
checkbox
Here's what I've tried
- using
onClickCapture
on each: checkbox, li, and both - calling
e.stopPropagation()
on each: checkbox, li, and both - calling
e.nativeEvent.stopPropagation()
on each: checkbox, li, and both - calling
e.nativeEvent.stopImmediatePropagation()
on each: checkbox, li, and both - calling
e.nativeEvent.preventDefault()
on each: checkbox, li, and both
With the code above, at some point the order became
row
checkbox
But the row
is always executed BEFORE the checkbox, so I can't see how make them not overlap.
Also worth mentioning that both handlers have logic, that need to happen, so making the row never execute any code is not an option.
This seems like a trivial thing, like I should know the answer to this. What am I missing?
Edit
Here's the minimal reproducible example: https://codesandbox.io/s/shy-shape-u1me4?file=/src/App.js
In the example above I stripped a lot of things like CSS classes. While doing that, I realised that what I'm actually clicking is a label
for the checkbox, and the checkbox is "hidden" in my app.
I solved the problem by moving the event handler to the label
instead of the checkbox, and running:
e.stopPropagation()
to prevent propagation to the parentli
.e.preventDefault()
to prevent the label to trigger the checkboxes o'clock, which would also cause the event to propagate to theli
above.
解决方案
The problem seem to be that my UI library hides the actual input
, and the visible area where I was clicking was actually the label
. These 2 elements are siblings related by the id
and htmlFor
attributes respectively.
As I was attaching the event handler on the input, but the label was the one actually being clicked, the propagation was not properly being stopped.
I solved the problem by moving the event handler to the label
instead of the checkbox, and running:
e.stopPropagation()
to prevent propagation to the parentli
.e.preventDefault()
to prevent the label to trigger the checkboxes o'clock, which would also cause the event to propagate to theli
above.
<li onClick={handleRowClick}>
<input id="c-1" type="checkbox" />
<label htmlFor="c-1" onClick={handleCheckboxClick}>Foo</label>
...
</li>
const handleCheckboxClick = () => {
e.stopPropagation()
e.preventDefault()
}
推荐阅读
- sql - 在sql中,当按部门分组时,如何将sal显示为null,部门中缺少成绩的等级
- java - 如何像在终端上运行一样准确地获取 Java 程序的输出?
- angular - 使用 Angular 组件时替代 href
- mongodb - 更新 mongodb 中的多个文档
- python - 如何在 Python 中使用带有协程的装饰器?
- dart - 制作非全屏 Flutter 路由
- flutter - 如何使用 tablelayout 像在颤动中看
- asp.net-mvc - 在 ASP.Net Core 中使用 SPA 预渲染和 JWT 承载身份验证实现 XSRF-Token
- amazon-web-services - 哪种机器采用 AWS 的 KMS 实例进行 500 到 500(多对多)视频会议
- jquery - 如何将 W1 类更改为 W2