浏览器事件捕获冒泡以及阻止冒泡
浏览器事件捕获冒泡以及阻止冒泡
一、浏览器的dom事件流
dom事件流有三个阶段,捕获阶段—>目标阶段—>冒泡阶段,不管是有没有绑定事件,只要发生点击事件,事件的处理将从DOM层次的根开始,而不是从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递,直到目标元素然后再从目标元素冒泡到根元素。这是事件触发后的整个固定流程,至于要在哪个点绑定事件看具体需要。
举个小例说明下:
<style>
* {
box-sizing: border-box;
}
#box1 {
height: 600px;
width: 500px;
padding-top: 100px;
background-color: red
}
#box2 {
height: 400px;
width: 500px;
padding-top: 100px;
background-color: green;
}
#box3 {
height: 200px;
width: 500px;
background-color: #000
}
</style>
<body> <div id="box1"> <div id="box2"> <div id="box3"></div> </div> </div> </body>
//正常点击dom1、dom2.dom3
<script> var dom1 = document.getElementById('box1'); var dom2 = document.getElementById('box2'); var dom3 = document.getElementById('box3');
dom3.addEventListener('click', function(){console.log('target')}); //被点击的目标target,是捕获还是冒泡不影响
dom1.addEventListener('click', function(){console.log('cp1')}, true); //true表示cp-capture捕获
dom2.addEventListener('click', function(){console.log('cp2')}, true);
dom3.addEventListener('click', function(){console.log('cp3')}, true);
dom3.addEventListener('click', function(){console.log('bb3')}, false);
dom1.addEventListener('click', function(){console.log('bb1')}, false); //bb-bubble冒泡
dom2.addEventListener('click', function(){console.log('bb2')}, false);
</script>
//点击dom3 输出结果依次为 cp1->cp2->target->cp3->bb3->bb2->1
//点击dom2 输出结果依次为 cp1->cp2->bb2->bb1
//点击dom1 输出结果依次为 cp1->bb1
//阻止冒泡(一般事件绑定在冒泡阶段)
<script>
var dom1 = document.getElementById('box1');
var dom2 = document.getElementById('box2');
var dom3 = document.getElementById('box3');
dom3.addEventListener('click', function(e){console.log('target3'); e.stopPropagation();//阻止冒泡}); //被点击的目标target3,是捕获还是冒泡不影响
dom2.addEventListener('click', function(e){console.log('target2'); e.stopPropagation();}); //被点击的目标target2,是捕获还是冒泡不影响
dom1.addEventListener('click', function(e){console.log('target1'); e.stopPropagation();}); //被点击的目标target1,是捕获还是冒泡不影响
dom1.addEventListener('click', function(){console.log('cp1')}, true); //true表示cp-capture捕获
dom2.addEventListener('click', function(){console.log('cp2')}, true);
dom3.addEventListener('click', function(){console.log('cp3')}, true);
dom3.addEventListener('click', function(){console.log('bb3')}, false);
dom1.addEventListener('click', function(){console.log('bb1')}, false); //bb-bubble冒泡
dom2.addEventListener('click', function(){console.log('bb2')}, false);
</script>
//点击dom3 输出结果依次为 target3
//点击dom2 输出结果依次为 target2
//点击dom1 输出结果依次为 target1
//以上在谷歌浏览器亲测正常!
需要注意的是,我们无法在事件捕获阶段阻止事件冒泡!!!
stiopPropagation()方法
stiopPropagation()方法的的官方解释为:终止事件在传播过程的捕获、目标处理或起泡阶段进一步传播。调用该方法后,该节点上处理该事件的处理程序将被调用,事件不再被分派到其他节点。
preventDefault()方法
取消事件的默认动作。
这个方法通知浏览器取消执行与事件关联的默认动作。如<a>标签的地址跳转等:
return false方法
对于这个方法,相信同学们一定不会陌生。在甚多时候,return false可以替代stopPropagation()和preventDefault()。
但是并不是所有的情况下都可以用return false来替代上两种方法。
因为return false方法:不但阻止事件执行,而且会跳出,return false之后的所有事件都不会执行。