事件冒泡、事件捕捉、事件代理(事件委托)

事件冒泡

如下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #div1 {
            height: 300px;
            width: 300px;
            background-color: red;
        }
        #div2 {
            height: 200px;
            width: 200px;
            background-color: black;
        }
    </style>
</head>
<body>
    <div id="div1">
        <div id="div2"></div>
    </div>
    <script>
        var div1 = document.getElementById('div1');
        var div2 = document.getElementById('div2');
        div1.addEventListener('click', function () {
            console.log('div1')
        }, false);
        div2.addEventListener('click', function () {
            console.log('div2')
        }, false);
    </script>
</body>
</html>

将上述代码在浏览器打开,当点击div2(黑色)元素,会执行其回调函数打印文字div2,同时也会触发元素div1的回调函数,打印文字div1。即在冒泡状态下子元素的点击状态会传递给父元素,一直传递到document对象,这就是事件冒泡。因此上述的点击状态传递过程为:

div2->div1->body->html->document   由内而外传播

在addEventListener中,第一个参数时事件,第二个参数时回调函数,第三个参数是决定回调函数执行的环境,默认为false(在事件冒泡时执行回调函数)。

事件捕捉

事件捕捉与事件冒泡正好相反,只需要将上述事件冒泡代码两个监听器中第三个参数改为true即可,true代表回调函数在事件捕捉时执行。

改为true之后,点击状态的传递变为如下:

div1->div2    由外而内传播

事件代理(事件委托)

事件代理其实就是利用事件冒泡的原理,进行一些复杂操作的简化。如下代码:

    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>

如果要对ul列表中所有li挂载事件,你可以手动写多个监听器去监听每一个li。当你在点击某一个li的时候,他的点击状态也会根据事件冒泡原理传递到ul中,我们可以根据这个原理,将所有li的事件都委托给ul,即将所有li的监听器只需要挂载在ul一个元素上即可,这样也能实现相同的效果。如下代码:

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <script>
        var ul = document.getElementsByTagName('ul')[0];
        ul.addEventListener('click' , function(){
            console.log('点击了')
        })
    </script>
</body>

阻止事件冒泡和默认事件

先看没有阻止事件冒泡和默认事件的代码:

<body>
    <ul id="ul1">
        <li id="li1">1</li>
    </ul>
    <a href="http://www.baidu.com" id="a">百度</a>
    <script>
        var ul = document.getElementById('ul1')
        var li = document.getElementById('li1');
        var a = document.getElementById('a');
        a.addEventListener('click' , function(){
            console.log('a被点击了')
        })
        ul.addEventListener('click' , function(){
            console.log('ul被点击了')
        })
        li.addEventListener('click' ,function(){
            console.log('li被点击了');
        })
    </script>
</body>

此代码大家可以运行一下查看效果,完全点击li会触发li和ul的回调函数,点击a标签会发生跳转。
下面我们来看一下设置阻止事件冒泡和阻止默认事件的代码:

<body>
    <ul id="ul1">
        <li id="li1">1</li>
    </ul>
    <a href="http://www.baidu.com" id="a">百度</a>
    <script>
        var ul = document.getElementById('ul1')
        var li = document.getElementById('li1');
        var a = document.getElementById('a');
        a.addEventListener('click' , function(e){
            e.preventDefault()
            console.log('a被点击了')
        })
        ul.addEventListener('click' , function(){
            console.log('ul被点击了')
        })
        li.addEventListener('click' ,function(e){
            console.log('li被点击了');
            e.stopPropagation()
        })
    </script>
</body>

其中我们在a标签的回调函数中接收事件回调函数并且获取事件参数e,调用e的preventDefault方法可以将a标签的调转行为取消。
其中我们在li标签的回调函数中接收事件回调函数并且获取事件参数e,调用e的stopPropagation函数可以将li的点击冒泡状态取消。

综上,做以下总结:

preventDefault()  取消默认事件  比如a标签、submit按钮
stopPropagation()  取消事件冒泡
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值