事件的传播

1. 一个事件发生后,会在子元素和父元素之间传播(propagation)。这种传播分成三个阶段。

  • 第一阶段:从window对象传导到目标节点(上层传到底层),称为“捕获阶段”(capture phase)
  • 第二阶段:在目标节点上触发,称为“目标阶段”(target phase)
  • 第三阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)

2. 这种三阶段的传播模型,使得同一个事件会在多个节点上触发

1 <div>
2   <p>点击</p>
3 </div>

    上面代码中,<div>节点之中有一个<p>节点

     如果对这两个节点,都设置click事件的监听函数(每个节点的捕获阶段和冒泡阶段,各设置一个监听函数),共计设置四个监听函数。然后,对<p>点击,click事件会触发四次

 1 var phases = {
 2   1: 'capture',
 3   2: 'target',
 4   3: 'bubble'
 5 };
 6 
 7 var div = document.querySelector('div');
 8 var p = document.querySelector('p');
 9 
10 div.addEventListener('click', callback, true);
11 p.addEventListener('click', callback, true);
12 div.addEventListener('click', callback, false);
13 p.addEventListener('click', callback, false);
14 
15 function callback(event) {
16   var tag = event.currentTarget.tagName;
17   var phase = phases[event.eventPhase];
18   console.log("Tag: '" + tag + "'. EventPhase: '" + phase + "'");
19 }
20 
21 // 点击以后的结果
22 // Tag: 'DIV'. EventPhase: 'capture'
23 // Tag: 'P'. EventPhase: 'target'
24 // Tag: 'P'. EventPhase: 'target'
25 // Tag: 'DIV'. EventPhase: 'bubble'

     上面代码表示,click事件被触发了四次:<div>节点的捕获阶段和冒泡阶段各1次,<p>节点的目标阶段触发了2次。

  1. 捕获阶段:事件从<div><p>传播时,触发<div>click事件;
  2. 目标阶段:事件从<div>到达<p>时,触发<p>click事件;
  3. 冒泡阶段:事件从<p>传回<div>时,再次触发<div>click事件。

       其中,<p>节点有两个监听函数(addEventListener方法第三个参数的不同,会导致绑定两个监听函数),因此它们都会因为click事件触发一次。所以,<p>会在target阶段有两次输出。

      注意,浏览器总是假定click事件的目标节点,就是点击位置嵌套最深的那个节点(本例是<div>节点里面的<p>节点)。所以,<p>节点的捕获阶段和冒泡阶段,都会显示为target阶段。

       事件传播的最上层对象是window,接着依次是documenthtmldocument.documentElement)和bodydocument.body。也就是说,上例的事件传播顺序,在捕获阶段依次为windowdocumenthtmlbodydivp,在冒泡阶段依次为pdivbodyhtmldocumentwindow。

posted @ 2021-05-13 14:20  icyyyy  阅读(191)  评论(0)    收藏  举报