JavaScript点击事件触发两次。

14
在下面的代码片段中,为什么当点击

1
@NishanthMatha 不确定这怎么成为那个问题的副本,因为那个问题中没有将事件附加到包含 div。 - Zze
1
@NishanthMatha,现在的问题如何与链接的问题重复? - guest271314
2
@NishanthMatha 但是 div 事件处理程序执行了两次,而不是输入处理程序。 - Andrew Li
1
@NishanthMatha 这如何解释目前在label元素上单击时,为什么divClicked会被调用两次的问题呢? - guest271314
1
@Zze 更正了评论的收件人 - guest271314
显示剩余4条评论
3个回答

17

这是因为HTML规范在4.10.4中描述的原因:

例如,在复选框标签可以勾选的平台上,单击以下代码片段中的

<label><input type=checkbox name=lost> Lost</label>

在其他平台上,行为可能只是将控件聚焦或不执行任何操作。

这意味着当单击

divClicked被触发两次的原因是,来自

,第二个合成的点击事件也冒泡到


说实话,我的答案包括规范的这一部分和更多内容,并逐步解释了冒泡过程。由于这个答案更短更简洁,所以更好。 - Andrew Li
在最后一行添加 e.preventDefault();,在我的情况下,它已经修复了。 - Wagner Pereira

0

这通常是由于 click 事件的冒泡原理造成的:

当一个元素上发生事件时,它会在该元素、其关联元素、其父级和其他祖先元素上运行。

现在,当你点击 label 时,有两个事件会冒泡到这里:

1) 点击 div(预期的)

2) 点击 input(也是预期的)

2.1) 当触发 input 的点击时,这里也会再次触发 div 的点击

您可以使用 event.bubbles 属性来确认此行为。

编辑:

连接 labelinput 的原因:(我知道这绝对不是必需的,因为它已经存在于所有地方)

一个 <label> 可以与控件相关联,方法是将控件元素放置在 <label> 元素内部,或使用 for 属性。这样的控件称为标签元素的标记控件。一个输入可以与多个标签相关联。
从这里获取:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label 这意味着在标签上放置 for 并引用输入元素的 id 将会模拟元素在 label 内部的行为。这将会像任何子元素到父元素的事件一样,将 input 上的事件冒泡到 label 上。

1
你只描述了一个事件,通过多个元素冒泡。冒泡不会创建多个事件,它只描述了一个事件如何触发所有祖先处理程序的行为。 - 4castle
@4castle 我想更重要的是高亮显示的 2.1 部分!事件冒泡的概念只是告诉我们,对标签的 click 或输入框的 click 会触发对 div 的点击...然后才是真正的原因,即 2.1 - Nishanth Matha
1
你回答中缺少的部分是:为什么点击标签会在输入元素上产生第二个独立的事件?你已经描述了冒泡,但没有解释为什么通过点击标签可以切换<input>处理程序,即使<input>不是<label>的祖先。 - 4castle
@4castle 这在互联网上已经到处都是了..(甚至在我对OP的评论中也有!)但如果你认为这是缺失的,请参考我的编辑!! - Nishanth Matha
1
您的编辑仍然没有说明为什么单击标签会触发对<input>的单击事件。事件不会向下冒泡到子元素或同级元素,只会冒泡到祖先元素。 - 4castle
让我们在聊天中继续这个讨论 - 4castle

-1
在某些时刻,还要检查一下 JavaScript 文件资源是否被加载了两次……虽然不应该发生,但你永远也不知道。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接