在这个例子中,我创建了一个带有标题的标签组,并试图将一个点击监听器附加到每个标签上。我最终希望input
每个内部都有一个label
,但没有必要说明我不理解的行为。
根据是否将标签文本包装在标签中,我看到了不同的行为span
:
span
,事件处理程序在label
元素上被调用一次,正如我期望的那样。span
,事件处理程序仍仅被调用一次,但这一次是子项span
而不是父项label
。在第二种情况下,我希望事件处理程序触发两次:一次触发父事件,一次触发label
子事件span
。有人可以解释为什么添加此span
元素似乎阻止事件处理程序传播给父级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
是作为事件目标的元素(span
在情况下为)<label><span>...</span></label>
。事件的目标是span
,然后事件传播(冒泡)到其父对象label
,由事件处理程序在其父对象处进行处理。
如果要查看label
,则按this
原样id
使用或使用e.currentTarget
(事件当前传递到的元素)。
旧的DOM3事件规范中的此图非常有助于理解事件流:
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句