JavaScript事件冒泡和事件捕获

Posted 开到荼蘼223's

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript事件冒泡和事件捕获相关的知识,希望对你有一定的参考价值。

事件流

事件流是指当事件发生时,会在发生事件的元素节点与DOM树根节点之间按特定的顺序进行传播的过程。IE的事件流是事件冒泡流(event bubbling),而Netscape的事件流是事件捕获流(event capturing)

事件冒泡

在这里插入图片描述

事件的冒泡(Bubble) 所谓的事件冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发。事件冒泡会从当前触发的事件目标一级一级往上传递,依次触发,直到document为止。
在这里插入图片描述

    <style>
        #box1{
            width: 200px;
            height: 200px;
            background-color: yellowgreen;
        }
        #s1{
            background-color: yellow;
        }
    </style>
    <div id="box1">
        我是box1
        <span id="s1">我是span</span>
    </div>
    <script>
        window.onload = function(){
            // 为s1绑定一个单击响应函数
            var s1 = document.getElementById('s1')
            s1.onclick = function(event){
                event == event || window.event
                alert('我是span的单击响应函数');
            }
            // 为box1绑定一个单击响应函数
            var box1 = document.getElementById('box1')
            box1.onclick = function(){
                alert('我是div的单击响应函数');
            }
            // 为body绑定一个单击响应函数
            document.body.onclick = function(){
                alert('我是body的单击响应函数');
            }
        }

可以发现当我们点击了span后,在触发span本身的事件后还会继续触发span父元素div的绑定相同的事件,并且一直延续到body绑定的相同事件, 这就是事件冒泡的体现。

在大部分情况下事件冒泡是对开发有利的,如事件委托机制就是利用事件冒泡这一特点,但如何取消事件冒泡呢?

可以通过事件对象取消事件冒泡,通过设置cancelBubble为true即可取消冒泡,或者也可以通过stopPropagation()方法取消事件冒泡。

        window.onload = function(){
            // 为s1绑定一个单击响应函数
            var s1 = document.getElementById('s1')
            s1.onclick = function(event){
                event == event || window.event
                alert('我是span的单击响应函数')
                // 取消冒泡
                // 可以将时间的cancelBubble设置为true 即可取消冒泡
                event.cancelBubble = true
                // event.stopPropagation()
            }

由此可以发现,当设置了 cancelBubble = true 或者调用stopPropagation( ) 方法后,当点击span后,自身事件触发后其父元素div和祖先元素body中的alert事件没有触发,取消了span的事件冒泡。

事件捕获

**事件捕获(event capturing)**相比于事件冒泡,事件会从最外层开始发生,直到最具体的元素。

    <!-- 事件捕获 -->
    <div>
        <button>
            <p>点击捕获</p>
        </button>
    </div>
    <script>
        var p = document.querySelector('p');
        var btn = document.querySelector('button');
        var div = document.querySelector('div');    
        p.addEventListener('click',function(){
            console.log('p标签被点击')
        },true);    
        btn.addEventListener('click',function(){
            console.log("button被点击")
        },true);    
        div.addEventListener('click',function(){
            console.log('div被点击')
        },true);
        document.body.addEventListener('click',function(){
            console.log('body被点击')
        },true);
    </script>

在这里插入图片描述
由控制台可以发现当我们点击p标签后,body绑定的事件是最先被触发的,依次向下传递直到最具体的目标标签p,同理想要取消事件捕获仍然可以调用事件对象的stopPropagation( ) 方法。

以上是关于JavaScript事件冒泡和事件捕获的主要内容,如果未能解决你的问题,请参考以下文章

事件冒泡/捕获 - 它从哪里开始/结束?

javascript中的事件冒泡事件捕获和事件执行顺序

JavaScript事件冒泡和事件捕获

JavaScript事件冒泡和事件捕获

js之事件冒泡和事件捕获及其阻止详细介绍

javascript中的事件冒泡和事件捕获