当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 浅谈js事件冒泡和事件捕获

浅谈js事件冒泡和事件捕获

2019年01月25日  | 移动技术网IT编程  | 我要评论
前言:最近正好在找工作,当面试官问到我事件冒泡和事件捕获的时候,我想我的回答并不全面合理,基于这方面的原因,我打算抽点时间来和大伙聊聊, 并不一定全面,多多包涵。 首先咱们先聊聊事件冒泡: 什么是事件冒泡 事件冒泡:如果一个元素的事件被触发,那么他的所有父级元素的同名事件也会被依次触发 元素->父元 ...

前言:最近正好在找工作,当面试官问到我事件冒泡和事件捕获的时候,我想我的回答并不全面合理,基于这方面的原因,我打算抽点时间来和大伙聊聊,

           并不一定全面,多多包涵。

 

首先咱们先聊聊事件冒泡:

什么是事件冒泡

  • 事件冒泡:如果一个元素的事件被触发,那么他的所有父级元素的同名事件也会被依次触发
  • 元素->父元素->body->html->document->window
  • 事件冒泡一直存在,只不过以前我们没有给父级元素加同名事件
<!doctype html>
<html>
<head lang="en">
    <meta charset="utf-8">
    <title></title>
    <style>
        #box{
            width: 300px;
            height: 300px;
            background-color: hotpink;
            position: relative;
        }

        #son{
            width: 100px;
            height: 100px;
            position: absolute;

            left: 350px;
            top: 350px;

            background-color: yellowgreen;
        }
    </style>
</head>
<body>

<div id="box">
    <input type="button" value="点我" id="btn"/>

    <div id="son"></div>
</div>

</body>
</html>

<script>

    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("我是骚粉的大盒子");
    };

    document.getelementbyid("btn").onclick = function () {

        alert("我是小按钮");
    };

    document.getelementbyid("son").onclick = function () {

        alert("我是又黄又绿的小盒子");
    };
</script>

 

事件冒泡的好处

  • 事件冒泡好处:如果想给父元素的多个子元素添加事件,我们可以只需要给父元素添加事件即可,然后
  • 通过获取事件源(e.target)就可以得知是哪一个子元素触发了这个事件
<!doctype html>
<html>
<head lang="en">
    <meta charset="utf-8">
    <title></title>
</head>
<body>

<ul id="ul1">
    <li>隔壁老王1</li>
    <li>隔壁老王2</li>
    <li>隔壁老王3</li>
    <li>隔壁老王4</li>
    <li>隔壁老王5</li>
</ul>

</body>
</html>

<script>

    var ul = document.getelementbyid("ul1");

    //1.如果想给ul中的每一个li标签添加点击事件,以前的做法需要遍历ul的li标签逐个添加
    //    for (var i = 0; i < ul.children.length; i++) {
    //
    //        ul.children[i].onclick = function () {
    //
    //            alert(this.innerhtml);
    //        }
    //    }

    //2.使用时间冒泡:只需要给父元素添加点击事件即可
    ul.onclick = function (e) {

        e = e || window.event;

        var target = e.target || e.srcelement;

        console.log(target.innerhtml);

        //target:事件源:触发本次事件的源头
        alert(e.target.innerhtml);
    }

</script>

事件冒泡的影响

  • 事件冒泡会导致需求冲突:例如我想要添加一个功能,弹出登录窗之后点击body空白区域让登陆窗消失
  • 此时a标签弹出登录窗的点击事件会触发body的点击事件,导致登陆窗一出来就消失

阻止事件冒泡

  • 阻止事件冒泡:让同名事件不要在父元素中冒泡(触发)
     * 说人话:点击一个元素只会触发当前元素的事件,不会触发父元素的同名事件
    
  • 语法: 事件对象.stoppropagation() ie8及之前不支持
  • 事件对象.cancelbubble = true ie8之前支持
  • 注意:如果想要阻止事件冒泡,一定要在触发事件的函数中接收事件对象

 

事件捕获

  • 1.事件冒泡:从触发事件元素,一级一级往上找父元素触发同名事件,如果有就触发
  • 2.事件捕获:从最顶级的父元素一级一级往下找子元素触发同名事件,直到触发事件的元素为止
    • 事件捕获与事件冒泡触发事件的顺序完全相反
  • 3.事件捕获,只能通过addeventlistener并且参数写true才是事件捕获
    • 其他都是冒泡(不是通过addeventlistener添加、addeventlistener参数为false)
  • 4.事件对象.stoppropagation() 除了可以阻止冒泡还可以阻止捕获
  • 5.ie8及以前没有捕获!
<!doctype html>
<html>
<head lang="en">
    <meta charset="utf-8">
    <title></title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background-color: hotpink;
            position: relative;
        }

        #son {
            width: 100px;
            height: 100px;
            position: absolute;

            left: 350px;
            top: 350px;

            background-color: yellowgreen;
        }
    </style>
</head>
<body>

<div id="box">

    <div id="son"></div>
</div>


</body>
</html>

<script>

var box = document.getelementbyid("box"); var son = document.getelementbyid("son"); 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) son.addeventlistener("click", function () { alert("这是son"); },true) </script>

事件的三个阶段

  • 1.事件一共有三个阶段:事件的执行顺序
    • 1--捕获阶段 :
    • 2--目标阶段 :
    • 3--冒泡阶段 :
  • 2.事件对象.eventphase 可以获得触发这个事件时,到底是哪个阶段
  • 3.先从最顶级往下一级一级捕获,然后到目标的捕获,目标的冒泡,再一级一级往上冒泡
<!doctype html>
<html>
<head lang="en">
    <meta charset="utf-8">
    <title>标题</title>
    <style>
        .one {
            width: 200px;
            height: 200px;
            background-color: pink;
        }
        .son {
            width: 100px;
            height: 100px;
            background-color: green;
            position: absolute;
            left: 250px;
            top: 250px;
        }
    </style>
</head>
<body>
<div class="one" id="box">
    <input type="button" value="按钮" id="btn"/>
    <div class="son" id="son"></div>
</div>

<script>
   
    var box = document.getelementbyid("box");
    var btn = document.getelementbyid("btn");
    var son = document.getelementbyid("son");

    document.addeventlistener("click",function (e) {
        alert("document"+ e.eventphase);
    },true) ;//true表示事件捕获,所以是阶段1,并且优先执行

    document.body.addeventlistener("click", function (e) {
        alert("哈哈,我是body"+ e.eventphase);
    },false);


    box.addeventlistener("click",function (e) {
        alert("哈哈哈,我是粉色的盒子box..."+ e.eventphase);
    },false);



    btn.addeventlistener("click",function (e) {
        alert("哈哈哈,我是按钮btn..."+ e.eventphase);
    },false);



    son.addeventlistener("click",function (e) {
        alert("嘻嘻嘻,我是绿色的盒子son"+ e.eventphase);

    },false);

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

 

 

 

 

 

 

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网