DOM事件传播机制(javascript)

首先,先用一张图(以HTML-->button为例)简单了解一下DOM事件传播机制的基本原理:

一个事件从触发到响应,会经历两个阶段(挖洞和冒泡的过程):

挖洞:先从根标签开始,逐层向子标签传递这个事件,直到遇见事件目标(button)结束,然后由事件目标开始响应事件,并且调用事件函数。

冒泡:事件目标响应事件,调用事件函数,逐层向父标签传递事件响应,直至HTML根标签结束。

注意:事件函数默认是在冒泡过程中调用的,可以通过addEventListener()设置第三个参数为True,改为挖洞过程调用。对于事件传播流程来看,挖洞总是在冒泡之前执行,对于最里层的事件目标也是如此。(例外的是,在火狐浏览器中,对于事件目标,挖洞函数和冒泡函数谁先绑定执行谁。)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>事件传播机制</title>
</head>
<body>
    <div id="div">
        <button id="btn">点我</button>
        <a href="http://www.baidu.com">百度一下</a>
    </div>
    <script>
        var button = document.getElementById("btn");
        var div = document.getElementById("div");
        var body = document.body;
        var html = document.documentElement;

        button.addEventListener("click",function(){ console.log("5,点击button") }, true)
        div.addEventListener("click",function(){ console.log("6,点击div") }, true)
        body.addEventListener("click",function(){ console.log("7,点击body") }, true)
        html.addEventListener("click",function(){ console.log("8,点击html") }, true)

        button.addEventListener("click",function(){ console.log("1,点击button") }, false)
        div.addEventListener("click",function(){ console.log("2,点击div") }, false)
        body.addEventListener("click",function(){ console.log("3,点击body") }, false)
        html.addEventListener("click",function(){ console.log("4,点击html") }, false)
    
        // 结果: 打印顺序: 8,7,6,1,5,2,3,4

        // 总结: 
        // 1, 一个事件从触发到响应,经历的流程是: 先由根标签html触发事件,然后一层一层向子标签传递这个事件,直到传递到事件目标(button)结束,这个过程叫挖洞过程, 然后由事件目标(button)开始响应事件,并调用事件函数, 然后一层一层向父标签传递事件响应, 直到html根标签结束, 这个过程叫冒泡过程
        // 2, 事件函数默认是在冒牌过程中调用的, 可以通过addEventListener设置第三个参数为true,改为挖洞过程调用
        // 3, 对于事件传播流程中的标签来说, 挖洞总是在冒泡之前执行, 对于最里层的事件目标也是如此, 但火狐浏览器不这样认为, 在火狐中,对于事件目标, 挖洞函数和冒泡函数谁先绑定先执行



        var a = document.querySelector("a")
        // 需求: div中有一个a标签, 点击div背景变蓝,点击a背景变红
        // a.addEventListener("click", function(e){ 
        //     e.preventDefault() // 阻止默认行为, 也就是a标签跳转
        //     body.style.backgroundColor = "red"
        // });
        // div.addEventListener("click", function(){
        //     body.style.backgroundColor = "blue"
        // })
        // 结果: 以上写法是错的, 不管点a还是div,都显示蓝色
        // 原因: a标签修改红色之后,冒泡给了父标签div,又改成了蓝色
        // 解决: 方案一, 阻止a标签的冒泡, 不让div执行冒泡函数
        a.addEventListener("click", function(e){ 
            e.preventDefault() // 阻止默认行为, 也就是a标签跳转
            body.style.backgroundColor = "red"
            // 阻止a标签的事件传播, 不会阻止a自身的冒泡
            // e.stopPropagation()
            // 立即阻止a标签的事件传播, 会把自身的冒泡也阻止掉
            e.stopImmediatePropagation()    
            console.log("a挖洞")
        },true);
        a.addEventListener("click", function(e){console.log("a冒泡")}, false)
        div.addEventListener("click", function(){
            body.style.backgroundColor = "blue"
        })
        // 解决: 方案二, 让div事件函数在挖洞过程执行, 这样点击a时,a的红色会替换div的蓝色
        a.addEventListener("click", function(e){ 
            e.preventDefault() // 阻止默认行为, 也就是a标签跳转
            body.style.backgroundColor = "red"
        });
        div.addEventListener("click", function(){
            body.style.backgroundColor = "blue"
        },true)

    </script>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值