事件属性与addEventListener - 属性捕获?

时间:2017-05-03 10:07:15

标签: javascript javascript-events event-handling

当使用javascript方法addEventListener(type,listener [,useCapture])时,我可以将useCapture标志设置为true。

如果为true,则useCapture表示用户希望启动捕获。启动捕获后,指定类型的所有事件将被分派到已注册的侦听器,然后再分派到DOM树中它下面的任何EventTarget。

HTML属性是否像onclick =“listener();”默认捕获?

1 个答案:

答案 0 :(得分:1)

  

如果为true,则useCapture表示用户希望启动捕获。

不,这意味着在事件周期的捕获(或目标)阶段而不是冒泡(或目标)阶段调用事件处理程序。来自the UI events spec的图表很好地传达了事件的三个​​阶段:

enter image description here

  

事件属性与addEventListener - 属性捕获?

不,当您使用旧DOM0 onxyz - 属性样式或属性样式事件处理时,就像使用false addEventListener参数:您正在设置处理程序对于鼓泡(或目标)阶段,而不是捕获阶段。

示例:

var outer = document.getElementById("outer");
var middle = document.getElementById("middle");
var inner = document.getElementById("inner");
hook(outer, false);
hook(outer, true);
outer.onclick = function() {
  console.log("outer: DOM0");
};
hook(middle, false);
hook(middle, true);
middle.onclick = function() {
  console.log("middle: DOM0");
};
hook(inner, false);
hook(inner, true);
inner.onclick = function() {
  console.log("inner: DOM0");
};

function hook(element, useCapture) {
  element.addEventListener("click", function(e) {
    var type;
    if (this === e.target) {
      type = "target (" + (useCapture ? "capture" : "bubbling") + " handler)";
    } else {
      type = useCapture ? "capture" : "bubbling";
    }
    console.log(this.id + ": " + type);
  }, useCapture);
}
.as-console-wrapper {
  max-height: 100% !important;
}
<div id="outer">
  <div id="middle">
    <div id="inner">
      Click Me
    </div>
  </div>
</div>

这给了我们输出:

outer: capture
middle: capture
inner: target (bubbling handler)
inner: target (capture handler)
inner: DOM0
middle: bubbling
middle: DOM0
outer: bubbling
outer: DOM0

注意:未定义DOM0处理程序相对于addEventListener(..., ..., false)处理程序的运行顺序。有些浏览器之前运行它们,其他浏览器运行它们。

输出说明:

  1. 捕获阶段:
    • 事件通过outer,因此运行outer的捕获处理程序。
    • 它通过middle,因此运行middle的捕获处理程序。
  2. 目标阶段:
    • 事件到达inner,因此所有inner的目标处理程序按其附加顺序运行。所以我们看到inner: target (bubbling handler)然后inner: target (capture handler),因为我们在钩住捕获处理程序之前已经使用冒泡处理程序。 (我这样做是为了强调目标阶段既不是冒泡也不是捕获,而是它自己的东西,并且同时捕获捕获和冒泡处理程序。)
    • 运行inner的DOM0处理程序(某些浏览器会在上面的处理程序之前执行此操作)。
  3. 鼓泡阶段
    • 事件冒泡到middle,因此运行middle冒泡处理程序,然后运行其DOM0处理程序(某些浏览器会先触发DOM0处理程序)
    • 运行事件气泡到outer,到outer的冒泡处理程序,然后运行它的DOM0处理程序(再次,顺序因浏览器而异)。