事件的冒泡与捕获(具体分析)

在介绍事件的冒泡与捕获之前,我们先介绍为一个元素注册多个相同事件:
比如: 我们给一个盒子注册两次点击事件

//可以给同名的事件,绑定多个事件处理程序

    //语法:对象.addEventListener(参数1,参数2,参数3);
    //参数1:事件名(字符串),不要加on  例如:click  、 mouseover 、mouseout
    //参数2:事件处理程序(函数名),当事件触发后哪个函数来处理
    //参数3:是一个bool类型,可以不传,默认为fasle(代表冒泡)跟冒泡和捕获有关
    //如果是true则表示捕获阶段

    //如果有同名事件不会覆盖,而是会依次执行
    //IE8及以前的版本不支持

     btn.addEventListener('click',function (  ) {
         alert('11111');
     },false);

    btn.addEventListener('click',function (  ) {
        alert('2222');
    },false);

现在介绍事件冒泡与事件捕获:
这里写图片描述

这里写图片描述

事件冒泡:

如果一个元素的事件被触发,那么它所有的父级元素的同名事件都会被触发.

注意点:只有当父级拥有同名事件的时候才会被触发.

window.onclick = function () {

        alert("window被点击了");
    }

    document.onclick = function () {

        alert("文档被点击了");
    }

    document.documentElement.onclick = function () {

        alert("html被点击了");
    }

    document.body.onclick = function () {

        alert("body被点击了");
    }

    document.getElementById("box").onclick = function () {

        alert("我是骚粉的大盒子");
    };

上述代码的执行顺序是:
box元素--> body-->HTML-->document-->window

事件捕获:
从最顶级的父元素一级一级往下找子元素触发同名事件,直到触发事件的元素为止.

注意点1:是去寻找与与父元素注册的同名事件的子元素
注意点2:因为事件捕获,只能通过addEventListener并且参数写true才是事件捕获
注意点3:其他情况都是冒泡(不是通过addEventListener添加、addEventListener参数为false)

window.addEventListener("click", function () {
        alert("这是window");
    },true)


    document.addEventListener("click", function () {
        alert("这是document");
    },true)

    document.documentElement.addEventListener("click", function (e) {
        e = e || window.event;
        alert("这是html");
//        e.stopPropagation();//阻止事件冒泡和事件捕获

    },true)

    document.body.addEventListener("click", function () {

        alert("这是body");

    },true)

    //参数3:默认是false,代表是支持事件冒泡
    box.addEventListener("click", function () {

        alert("这是box");
    },true)

上述代码的执行顺序是:
window-->document-->HTML-->body-->box元素

我们知道了事件捕获以及事件的冒泡原理,但是有的时候,我们就只想让其子元素单独触发或者让其父元素单独触发,此时就需要用到阻止事件的捕获以及冒泡的方法.

 * 1.阻止事件冒泡:让同名事件不要在父元素中冒泡(触发)
 * 说人话:点击一个元素只会触发当前元素的事件,不会触发父元素的同名事件
 * 语法:  事件对象.stopPropagation()       IE8及之前不支持
 *       事件对象.cancelBubble = true               IE8之前支持

 * 注意:如果想要阻止事件冒泡,一定要在触发事件的函数中接收事件对象


 *2.阻止事件捕获:
  *事件对象.stopPropagation() 除了可以阻止冒泡还可以阻止捕获

  *IE8及以前没有捕获!

好了,我们利用事件的冒泡写一个案例:

需求:移入li标签颜色改变.

思路:如果想给父元素的多个子元素添加事件,我们可以只需要给父元素添加事件即可,然后通过获取事件源(e.target)就可以得知是哪一个子元素触发了这个事件

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            border: 1px solid red;
            width: 500px;
            text-align: center;
            margin: 100px auto;
        }
        #ul1 li {
            list-style: none;
            line-height: 30px;
            font-size: 20px;
            border: 1px solid #ccc;

        }
    </style>
</head>

<body>

<ul id="ul1">
    <li>我是第1个li标签</li>
    <li>我是第2个li标签</li>
    <li>我是第3个li标签</li>
    <li>我是第4个li标签</li>
    <li>我是第5个li标签</li>
    <li>我是第6个li标签</li>
    <li>我是第7个li标签</li>
    <li>我是第8个li标签</li>
    <li>我是第9个li标签</li>
    <li>我是第10个li标签</li>
</ul>

<script>
    //需求: 1.给10个li标签移入添加背景高亮
    //      2.移出背景颜色恢复

    //思路:
    // 给ul注册鼠标移入事件,通过获取事件源(e.target)就可以得知是哪一个子元素触发了这个事件

    var ul1 = document.getElementById("ul1");

    var DefalutColor = null;  //全局变量存储默认的背景色
    ul1.onmouseover = function(e){
        //获取到的是对应的li标签对象
        // console.log(e.target);
        DefalutColor = e.target.style.backgroundColor; //将li标签默认的背景色赋给defalutColor
        e.target.style.backgroundColor = 'yellow';
    }

    ul1.onmouseout = function(e){
        e.target.style.backgroundColor = DefalutColor; //li标签默认的背景色
    }


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

我们现在来探讨jQuery里面的关于事件的操作:

//解绑事件
$(selector).off();
注意点:
     *1.如果不传参数就是解绑所有事件
     *2.如果传参数就是解绑指定事件

//事件的触发
$(selector).click();

// event.stopPropagation()    阻止事件冒泡行为
// event.preventDefault()    阻止浏览器默认行为
// return false:既能阻止事件冒泡,又能阻止浏览器默认行为。

猜你喜欢

转载自blog.csdn.net/weixin_42839080/article/details/81909675