事件冒泡:当某个子标签的事件被触发后,执行完绑定该事件的函数后,会依次触发所有的父标签事件,一直传递到根标签,在这个标签嵌套关系链中,如果某个标签绑定了同名事件,则执行该事件,否则继续向上一级传递;也可以理解为这种比较粗暴的说法:事件冒泡顾名思义就是往外冒,从里到外依次触发绑定的同名事件函数。
事件捕获:当用户触发某个标签后,会从根标签开始逐层向子标签寻找该事件的标签。延续粗暴的风格,事件捕获就是从外到里。
直接上例子吧:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{
margin:0;
padding:0;
}
#box{
width:500px;
height:500px;
background:red;
}
#div1{
width:300px;
height: 300px;
background:skyblue;
}
#div2{
width:100px;
height:100px;
background:orange;
}
</style>
<script>
window.onload = function(){
var box = document.querySelector('#box');
var div1 = document.querySelector('#div1');
var div2 = document.querySelector('#div2');
div2.onclick = function(){
alert('我是橙色盒子');
}
div1.onclick = function(){
alert('我是蓝色盒子');
}
box.onclick = function(){
alert('我是红色盒子');
}
}
</script>
</head>
<body>
<div id="box">
<div id="div1">
<div id="div2"></div>
</div>
</div>
</body>
</html>
跑完这段代码,点击橙色盒子之后,会看到这种景象,依次弹出三个弹窗,分别是我是橙色盒子,我是蓝色盒子,我是红色盒子。
其实我们本意只是想要看到显示 ‘’我是橙色盒子‘’的弹窗,为什么会接连触发另外两个盒子呢,这就是事件冒泡搞的鬼,那该如何解决这种问题呢?
解决方案一:stopPropagation( )阻止事件冒泡
<script>
window.onload = function(){
var box = document.querySelector('#box');
var div1 = document.querySelector('#div1');
var div2 = document.querySelector('#div2');
div2.onclick = function(ev){
var e = event || ev;
e.stopPropagation();
alert('我是橙色盒子');
}
div1.onclick = function(ev){
var e = window.event || ev;
e.stopPropagation();
alert('我是蓝色盒子');
}
box.onclick = function(ev){
var e = window.event || ev;
e.stopPropagation();
alert('我是红色盒子');
}
}
</script>
再次执行之后,你会发现我们在点击橙色盒子的时候,其他事件不会继续冒泡了。
解决方案二 : cancelBubble = true;
<script>
window.onload = function(){
var box = document.querySelector('#box');
var div1 = document.querySelector('#div1');
var div2 = document.querySelector('#div2');
div2.onclick = function(ev){
var e = event || ev;
e.cancelBubble = true;
alert('我是橙色盒子');
}
div1.onclick = function(ev){
var e = window.event || ev;
e.cancelBubble = true;
alert('我是蓝色盒子');
}
box.onclick = function(ev){
var e = window.event || ev;
e.cancelBubble = true;
alert('我是红色盒子');
}
}
</script>
也能达到同样效果。
事实上stopPropagation和cancelBubble的作用是一样的,都是用来阻止浏览器默认的事件冒泡行为。
两种方法作用都是一样的,都是阻止事件冒泡行为,区别在于cancelBubble 是为了兼容IE浏览器,stopPropagation是为了供谷歌、火狐等浏览器使用,两者可以结合使用。
看到这里,你可能有些疑惑,事件冒泡感觉还是没什么卵用啊
我们设想一下这个场景:
我们需要让鼠标滑过li标签显示某些内容,如果给每一个li标签都添加事件是不是有些消耗性能。如果我给ul添加事件,是不是不用遍历li标签了,这样做提高了代码执行效率。