【问题标题】:Is html label stopping propagation?html标签是否停止传播?
【发布时间】:2015-11-11 14:53:59
【问题描述】:

为什么当我在带有黑色边框的框内单击时,切换不执行,但当我在外部单击时,它会执行,但不是复选框?

var checks = document.querySelectorAll("ul li");

for (var i = 0; i < checks.length; i++) {
  checks[i].addEventListener("click", tog);
};

function tog(e) {
  e.currentTarget.classList.toggle("active");
}
ul li {
  background: #3CF;
  padding: 0.25em 0.5em;
  margin: 0.25em 0;
  display: block;
  cursor: pointer;
  text-indent: 1.5em;
}
ul li.active {
  background: #6EF;
}
label {
  display: block;
  width: 100px;
  border: 1px solid black;
}
<ul>
  <li>
    <label>
      <input type="checkbox">1
    </label>
  </li>
  <li>
    <label>
      <input type="checkbox">2
    </label>
  </li>
  <li>
    <label>
      <input type="checkbox">3
    </label>
  </li>
</ul>

【问题讨论】:

    标签: javascript html css dom-events


    【解决方案1】:

    没有。正如我在other answer 中解释的那样。由于lable 标记的进出冒泡,tog 函数被调用两次。因此li 标签一个接一个地接收两个相同的事件,因此active 类被添加和删除背靠背,导致此问题。

    您可以在fiddle 中使用警报查看此信息。


    我们可以通过使用事件的target 属性来避免这种情况。这是fiddle,按照您的要求工作。

    var checks = document.querySelectorAll("ul li");
    
    for (var i = 0; i < checks.length; i++) {
      checks[i].addEventListener("click", tog);
    };
    
    var i = 0;
    function tog(e) {
            if(e.target.tagName.toLowerCase() == 'label') {
                i++;  //if we remove this then i will never increment
                if(i%2 != 0) {
                    i++;  //to bring back to even, so next click should work fine
                    return;
                }
            }
      e.currentTarget.classList.toggle("active");
    }
    ul li {
      background: #3CF;
      padding: 0.25em 0.5em;
      margin: 0.25em 0;
      display: block;
      cursor: pointer;
      text-indent: 1.5em;
    }
    ul li.active {
      background: #6EF;
    }
    label {
      display: block;
      width: 100px;
      border: 1px solid black;
    }
    <ul>
      <li>
        <label>
          <input type="checkbox">1
        </label>
      </li>
      <li>
        <label>
          <input type="checkbox">2
        </label>
      </li>
      <li>
        <label>
          <input type="checkbox">3
        </label>
      </li>
    </ul>

    您可以通过使用 IIFE 返回函数处理程序或使用闭包来避免 i 全局变量。

    【讨论】:

    • 能否避免二次冒泡?
    • 正如我在评论中解释的答案。 jsfiddle.net/hvv6ucu8/7 甚至,传递的事件对象是相同的,所以我用可能的解决方法更新了我的答案,但我猜没有直接的方法。
    • 你能扩展上面的小提琴吗?我看不出这将如何使用多个标签和一个 i 变量
    • 由于事件是背靠背触发的,而且JS也是单线程的。如果标签触发 onclick,它必须完成另一个,它将被触发。所以,我不会为每个人都保持li 的状态,因为i 将始终处于稳定状态。 (检查代码中的 cmets)。 i只是用来检查,是不是二次火
    猜你喜欢
    • 1970-01-01
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    • 2022-05-28
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    相关资源
    最近更新 更多