当“标签"元素包含子“跨度"时,单击标签会在子而不是父上触发 [英] When a `label` element contains a child `span`, clicking the label triggers on the child but not the parent
问题描述
在此示例中,我创建了带有标题的标签组,并尝试将点击侦听器附加到每个标签;我最终希望在每个label
中都包含一个input
,但是没有必要说明我不理解的行为.
In this example, I've created a label group with a header, and have attempted to attach a click listener to each label; I eventually want an input
inside each label
, but it is not necessary to illustrate the behavior I don't understand.
根据是否将标签文本包装在span
标记中,我看到了不同的行为:
I am seeing different behavior depending on whether I wrap the label text in a span
tag:
- 单击标签没有子
span
时,事件处理程序将在label
元素上被调用一次,正如我期望的那样. - 单击带有带有子项的标签时,事件处理程序仍仅被调用一次,但这一次是子级
span
而不是父级label
.
- When the label without a child
span
is clicked, the event handler is called once as I would expect, on thelabel
element. - When the label with a child a
span
is clicked, the event handler is still called only once, but this time for the childspan
and not for the parentlabel
.
在第二种情况下,我希望事件处理程序触发两次:一次针对父级label
,一次针对子级span
.有人可以解释为什么添加此span
元素似乎阻止事件处理程序传播给父label
的原因吗?
I would have expected, in the second scenario, the event handler to trigger twice: once for the parent label
, and once for the child span
. Can someone explain why the addition of this span
element seems to be preventing the event handler from propagating to the parent label
?
var settingsGroup = document.getElementById("settings");
settingsGroup.querySelectorAll('.setting').forEach(function(setting) {
var options = setting.querySelectorAll('label');
options.forEach(function(option) {
option.addEventListener("click", function(ev) {
console.log(`${this.id} clicked: ${ev.target.tagName}`);
});
});
});
<div id="settings">
<div class="setting" role="group">
<div id="header">
<em>
A setting
</em>
</div>
<label id="option-a">
Option A
</label>
<label id="option-b">
<span>
Option B
</span>
</label>
</div>
</div>
推荐答案
这很正常. e.target
是作为事件目标的元素(在<label><span>...</span></label>
情况下为span
.事件的 target 是span
,然后事件传播(气泡)到其父label
,由事件处理程序处理.
This is normal. e.target
is the element that was the target of the event (the span
in the case of <label><span>...</span></label>
. The target of the event is the span
, and then the event propagates (bubbles) to its parent label
, where it gets handled by your event handler.
如果要查看label
,请像使用id
一样使用this
,或者使用e.currentTarget
(事件当前传递到的元素).
If you want to look at the label
instead, either use this
as you have for id
, or use e.currentTarget
(the element the event is currently being delivered to).
此图摘自旧的 DOM3事件规范在了解事件流方面很方便:
This diagram from the old DOM3 Events spec is handy for understanding event flow:
这篇关于当“标签"元素包含子“跨度"时,单击标签会在子而不是父上触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!