当“标签"元素包含子“跨度"时,单击标签会在子而不是父上触发 [英] When a `label` element contains a child `span`, clicking the label triggers on the child but not the parent

查看:153
本文介绍了当“标签"元素包含子“跨度"时,单击标签会在子而不是父上触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此示例中,我创建了带有标题的标签组,并尝试将点击侦听器附加到每个标签;我最终希望在每个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 the label element.
  • When the label with a child a span is clicked, the event handler is still called only once, but this time for the child span and not for the parent label.

在第二种情况下,我希望事件处理程序触发两次:一次针对父级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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆