js事件捕获 目标阶段 事件冒泡

1. 事件阶段

参考文章
https://segmentfault.com/a/1190000012729080

W3C的DOM事件流包含三个阶段
事件捕获
目标阶段
事件冒泡

IE事件流,不支持事件捕获

js事件捕获 目标阶段 事件冒泡

  1. 处于相应阶段内的元素,响应事件就是按照事件的注册顺序来进行相应阶段的触发,比如都是捕获阶段的多个处理函数,就会依照注册顺序执行
  2. stopImmediatePropagation会阻止事件的传播,也会阻止在其执行之后注册的事件的执行
  3. 由第一点理解,在目标阶段,元素的事件是按照注册的顺序执行的,此时没有冒泡和捕获的区别,都是顺序执行事件处理函数
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #dv1 {
            width: 300px;
            height: 300px;
            background-color: pink;
        }

        #dv2 {
            width: 250px;
            height: 250px;
            background-color: red;
        }

        #dv3 {
            width: 200px;
            height: 200px;
            background-color: blue;
        }
    </style>
</head>
<body>
<div id="dv1">
    <div id="dv2">
        <div id="dv3"></div>
    </div>
</div>

<script src="common.js"></script>
<script>
    // 事件阶段:
    // 1---捕获阶段-----从外向里
    // 2---目标阶段-----最开始被选择的那个
    // 3---冒泡阶段-----从里向外
    // DOM2级事件,规定事件流有上述三个阶段,首先发生事件捕获,从document这个不太具体的节点开始接收事件
    // 向内找到最具体的节点,就是目标,然后目标接收事件
    // 最后再向外向document冒泡
    // https://segmentfault.com/a/1190000012729080

    // function f1() {
    //     console.log("dv1");
    // }
    // function f2() {
    //     console.log("dv2");
    // }
    // function f3() {
    //     console.log("dv3");
    // }
    //
    // my$("dv1").addEventListener("click", f1, false);
    // my$("dv1").addEventListener("click", f1, true);
    // my$("dv2").addEventListener("click", f2, false);
    // my$("dv2").addEventListener("click", f2, true);
    // my$("dv3").addEventListener("click", f3, false);
    // my$("dv3").addEventListener("click", f3, true);

    var a = my$("dv1");
    var b = my$("dv2");
    var c = my$("dv3");

    c.addEventListener("click", function (event) {
        console.log("c1"+"----------"+event.eventPhase);
        // 注意第三个参数没有传进 false , 因为默认传进来的是 false
        //,代表冒泡阶段调用,个人认为处于目标阶段也会调用的
    });
    c.addEventListener("click", function (event) {
        console.log("c2"+"----------"+event.eventPhase);
    }, true);
    b.addEventListener("click", function (event) {
        console.log("b"+"----------"+event.eventPhase);
    }, true);
    a.addEventListener("click", function (event) {
        console.log("a1"+"----------"+event.eventPhase);
    }, true);
    a.addEventListener("click", function (event) {
        console.log("a2"+"----------"+event.eventPhase)
    });
    a.addEventListener("click", function (event) {
        console.log("a3"+"----------"+event.eventPhase);
        // event.stopImmediatePropagation();
    }, true);
    a.addEventListener("click", function (event) {
        console.log("a4"+"----------"+event.eventPhase);
    }, true);


</script>

</body>
</html>

2. 阻止事件冒泡

IE8 attachEvent/detachEvent—>火狐不支持,谷歌支持
标准:addEventListener/removeEventListener()三个参数,最后一个,false时,冒泡

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /**
     * 相同点:都可以为元素绑定事件
     * 不同点:
     * 1. 方法名不同
     * 2. 参数数不同,对象.addEventListener(type, fn ,false),对象.attachEvent(type, fn);
     * 3. 浏览器支持不同,第一个火狐 谷歌 IE11 OK  IE8不OK      第二个 IE8ok   谷歌火狐IE11不OK
     * 4. 事件类型,一个加on,一个不加on
     * 5. this,对象.addEventListener,是当前绑定事件的对象
     *            对象.attachEvent,是window
     *
     */
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #dv1 {
            width: 300px;
            height: 300px;
            background-color: pink;
        }

        #dv2 {
            width: 250px;
            height: 250px;
            background-color: red;
        }

        #dv3 {
            width: 200px;
            height: 200px;
            background-color: blue;
        }
    </style>
</head>
<body>
<div id="dv1">
    <div id="dv2">
        <div id="dv3"></div>
    </div>
</div>

<script src="common.js"></script>
<script>
    // 事件冒泡:当多个标签嵌套,然后都注册了相同的事件,那么里面的标签事件触发的时候,外面的也会触发
    // window.event.cancelBubble = true;------->IE8特有的,谷歌可以,火狐不可以,
    // IE8的事件处理参数对象是window.event--->用的是属性
    // e.stopPropagation();----->火狐谷歌可以,IE8不可以,这是火狐的事件处理参数对象--->用的是方法
    my$("dv1").onclick=function(){
        console.log("dv1");
    };
    // 事件处理参数对象,IE8没有
    my$("dv2").onclick=function(e){
        console.log("dv2");
        // window.event.cancelBubble = true;
        console.log(e);
        e.stopPropagation();

    };
    my$("dv3").onclick=function(e){
        console.log("dv3");
        e.stopPropagation();
    };
</script>

</body>
</html>

相关文章:

  • 2022-12-23
  • 2021-10-23
  • 2022-12-23
  • 2021-11-04
  • 2022-12-23
  • 2021-11-26
  • 2021-11-20
  • 2022-12-23
猜你喜欢
  • 2021-08-23
  • 2021-09-02
  • 2022-12-23
  • 2017-12-02
  • 2019-08-13
  • 2022-12-23
相关资源
相似解决方案