事件的传播
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次。
- 捕获阶段:事件从
<div>向<p>传播时,触发<div>的click事件; - 目标阶段:事件从
<div>到达<p>时,触发<p>的click事件; - 冒泡阶段:事件从
<p>传回<div>时,再次触发<div>的click事件。
其中,<p>节点有两个监听函数(addEventListener方法第三个参数的不同,会导致绑定两个监听函数),因此它们都会因为click事件触发一次。所以,<p>会在target阶段有两次输出。
注意,浏览器总是假定click事件的目标节点,就是点击位置嵌套最深的那个节点(本例是<div>节点里面的<p>节点)。所以,<p>节点的捕获阶段和冒泡阶段,都会显示为target阶段。
事件传播的最上层对象是window,接着依次是document,html(document.documentElement)和body(document.body)。也就是说,上例的事件传播顺序,在捕获阶段依次为window、document、html、body、div、p,在冒泡阶段依次为p、div、body、html、document、window。

浙公网安备 33010602011771号