之前对于事件冒泡流和捕获流的理解只停留在了大概了解的程度,只知道什么时候该用事件委派和阻止事件冒泡,而没有理解背后的原理,直到用代码看到dom事件流的过程,才理解这两个操作的意义。
三种事件流:
事件冒泡流:ie
事件捕获流:netscape
dom事件流:捕获阶段、处于目标阶段、冒泡阶段
捕获阶段:事件从根节点流向目标节点,触发沿途各节点上的捕获事件,最终到达目标节点。作用是建立传播路经,在冒泡阶段根据这个路经回溯到文档根节点。
目标阶段:事件到达目标节点时,进入目标阶段,事件在目标节点上被触发。
冒泡阶段:事件在目标节点上触发后,不会终止,一层层向上冒,回溯到根节点。
下面用一段代码模拟dom事件流的过程
<div class="a">
<li class="b">
<a href="#" class="c">点击</a>
</li>
</div>
<script>
var div = document.getElementsByClassName('a')[0];
var li = document.getElementsByClassName('b')[0];
var a = document.getElementsByClassName('c')[0];
//第三个参数默认是false,默认为冒泡阶段处理
div.addEventListener('click',function(event){
console.log('冒泡阶段div');
});
li.addEventListener('click',function(event){
console.log('冒泡阶段li');
});
a.addEventListener('click',function(event){
console.log('冒泡阶段a');
});
//第三个参数设为true,事件捕获阶段处理
div.addEventListener('click',function(event){
console.log('捕获阶段div');
},true);
li.addEventListener('click',function(event){
console.log('捕获阶段li');
},true);
a.addEventListener('click',function(event){
console.log('捕获阶段a');
},true);
</script>
运行结果为:
捕获阶段div
捕获阶段li
冒泡阶段a
捕获阶段a
冒泡阶段li
冒泡阶段div
由此引出了事件委派和阻止事件冒泡这两个操作
事件委派:只需把事件处理器添加到父元素上,便可以以通过事件捕获流让子元素可以触发事件。
阻止事件冒泡:防止在点击子元素时,由于事件冒泡流而触发父元素上的点击事件。将添加代码 event.stopPropagation(); 或者将addEventListener()第三个参数设置为true,可阻止事件冒泡。