一、什么是事件冒泡

事件冒泡表示的是在如果子节点(对象)触发某个事件,那么默认情况下,这个事件会向这个节点(对象)的父级对象传播,导致父级对象也会相应这个事件。

<div id="dad">
    <button id="son">点我</button>
</div>
 
<script>
var dad = document.getElementById("dad")
dad.onclick = function(){
    console.log("dad")
}
var son = document.getElementById("son")
son.onclick = function(){
    console.log("son")
}
</script>

上面的代码,点击 button 后,先输出 son ,然后还会输出 dad,这就是事件冒泡。

二、事件冒泡有什么作用

冒泡允许我们利用事件委托——这个概念依赖于这样一个事实,如果你想要在大量子元素中单击任何一个都可以运行一段代码,您可以将事件监听器设置在其父节点上,并让子节点上发生的事件冒泡到父节点上,而不是每个子节点单独设置事件监听器。

一个很好的例子是一系列列表项,如果你想让每个列表项被点击时弹出一条信息,您可以将click单击事件监听器设置在父元素<ul>上,这样事件就会从列表项冒泡到其父元素<ul>上。

<body>
    <ul id="dad">
        <li value="1">1</li>
        <li value="2">2</li>
        <li value="3">3</li>
    </ul>
</body>
<script>
var dad = document.getElementById("dad")
dad.onclick = function(event){
    if (event.target.Nodename.toLocalLowerCase =="li"){
        alert(event.target.value)
    }
}
</script>

当有li标签被点击之后,事件会传到父标签,然后父标签可以通过函数的event自带参数去判断是不是li标签被点击了,如果是就取出其中的值,显示。

三、阻止事件冒泡

先现代开发中,我们通常都会精确事件的触发对象,并不需要浏览器再去漫无目的的寻找。同时事件冒泡在很多时候会带来意想不到的bug,因此大多数情况下,我们需要阻止事件冒泡。

现代浏览器都支持Event 接口的 stopPropagation() 方法,通过该方法就可以阻止事件冒泡。

function showMsg(obj,e){
    console.log(obj.mes);
    e.stopPropagation();
}

注:万恶的IE8浏览器不支持上面的写法,需要使用 window.event.cancelBubble 来阻止事件冒泡,因此也可以自定义一个兼容的阻止事件冒泡函数:

function showMsg(obj,e){
    console.log(obj.mes);
    stopBubble(e);
}

function stopBubble(e) {
if ( e && e.stopPropagation )
    //支持W3C的stopPropagation()方法
    e.stopPropagation();
else
    //使用IE8的方式来取消事件冒泡
    window.event.cancelBubble = true;
}