首页 > 解决方案 > 停止冒泡时会先调用哪个事件?

问题描述

捕获后,将执行冒泡,但是当我stopPropagation()在冒泡阶段调用时会发生什么?

事件执行流程会改变吗?

var element1 = document.getElementsByClassName('element1')[0],
  element2 = document.getElementsByClassName('element2')[0],
  element3 = document.getElementsByClassName('element3')[0],
  foo = function(e) {
    console.log(this.className);
  },
  stop = function(e) {
    console.log('prevent', this.className);
    e.preventDefault();
  },
  stop1 = function(e) {
    console.log('stop', this.className);
    e.stopPropagation();
  };

element1.addEventListener('click', foo); // bubbling
element1.addEventListener('click', foo, true); // caputring
// You cab change handler to "stop"
element2.addEventListener('click', foo);
element2.addEventListener('click', foo, true);
element3.addEventListener('click', stop1);
element3.addEventListener('click', foo, true);
.element1 {
  background-color: #b0c4de;
  height: 160px;
  width: 400px;
  cursor: pointer;
}

.element2 {
  background-color: pink;
  height: 80px;
  width: 300px;
  position: relative;
  top: 20px;
  left: 50px;
}

.element3 {
  background-color: lightgreen;
  height: 30px;
  width: 200px;
  position: relative;
  top: 10px;
  left: 50px;
}
<h3>Please open Chrome console and click element3</h3>
<div class="element1">element1
  <div class="element2">element2
    <div class="element3">element3</div>
  </div>
</div>

jsfiddle 示例

对于以上一个预期的输出是

element1
element2
element3
stop element3

输出是

element1
element2
stop element3
element3

标签: javascriptjquerystoppropagation

解决方案


stopPropagation防止当前事件的进一步传播。传播意味着如果您从一个元素转到下一个元素(而不是从事件侦听器到下一个元素)。在element3这种情况下,既不在冒泡阶段,也不在捕获阶段,而是在目标阶段:

3. DOM 事件架构

  • 捕获阶段:事件对象通过目标的祖先从窗口传播到目标的父级。此阶段也称为捕获阶段。

  • 目标阶段:事件对象到达事件对象的事件目标。此阶段也称为目标阶段。如果事件类型表明事件没有冒泡,则事件对象将在此阶段完成后停止。

  • 冒泡阶段:事件对象以相反的顺序通过目标的祖先传播,从目标的父级开始,到窗口结束。此阶段也称为冒泡阶段。

因此,如果您处于目标阶段,那么事件处理程序是否附加为冒泡或捕获并不重要,因为在从捕获到冒泡的转换过程中不会传播到另一个元素。因此,事件处理程序按照它们附加的顺序执行,忽略阶段标志。

因此,如果您调用stopPropagation它,它将阻止传播到下一个元素,但是所有事件侦听器,element3无论它们是否在哪里添加,都会useCapture被调用。


推荐阅读