美文网首页让前端飞JavaScript 进阶营
讲个故事,顺便理解DOM事件模型

讲个故事,顺便理解DOM事件模型

作者: 临安linan | 来源:发表于2019-04-12 10:51 被阅读2次

    事件捕获和事件冒泡

    我们先写一段代码,爷爷嵌套爸爸,爸爸再嵌套儿子,再给他们添加相应的点击事件

    <!-- HTML -->
    <div id="grand">
          <div id="father">
               <div id="child"></div>
          </div>
    </div>
    
    // CSS
    div#grand{
        background-color: red;
        width: 500px;
        height: 500px;
    }
    div#father{
        background-color: green;
        width: 400px;
        height: 400px;
    }
    div#child{
        background-color: yellow;
        width: 200px;
        height: 200px;
    }
    
    var div = document.getElementsByTagName("div");
    div[0].addEventListener('click',function(){
        console.log("爷爷被点了");
    },false);
    
    div[1].addEventListener('click',function(){
        console.log("爸爸被点了");
    },false);
    
    div[2].addEventListener('click',function(){
        console.log("儿子被点了");
    },false);
    

    点最里面的儿子

    image.png
    为什么爸爸和爷爷都被点了?
    其实这就涉及到了事件冒泡和捕获

    先来看张图


    image.png

    我来简单模拟一下儿子被点击后发生了什么:

    • (从左边的捕获阶段开始)首先问爷爷,你的孙子被点了,你有没有事件响应一下,然后再问爸爸,你的儿子被点了,你有没有事件响应一下,最后再问儿子自己,你被点了,有没有事件响应一下。这个阶段叫捕获阶段。
    • 这一个阶段问完之后,从儿子开始往上又重复一次,问爸爸,再问爷爷,这就是DOM事件流。这个阶段叫冒泡阶段。
    • (其实爷爷上面还有body,document,window,这里为了方便理解就没有列出)

      简单下个定义,事件冒泡就是:从你点击的那个元素开始,逐级往上直到window,检查是否有冒泡阶段的执行事件

      事件捕获就是:点击内层元素,从最外围的window逐级往内直到被点击的元素,检查是否有捕获阶段的执行事件

    注:事件冒泡和捕获不单单只是点击事件才有,这里只是拿点击事件举例

    那问题来了,我上面给爷爷爸爸添加的点击事件,我怎么知道是捕获阶段的还是冒泡阶段的呢?

    答案就是:

    image.png
    addEventListener的第三个参数,填true,绑定的事件就是捕获阶段的,填false或不填,就是冒泡阶段的。

    再看这个图 是不是清晰多了 image.png
    事件流就是先进行捕获阶段的询问,有则响应,然后再进行冒泡阶段的询问,有则执行!

    假如爸爸或爷爷身上既有冒泡阶段的事件,又有捕获阶段的事件,根据事件流的规则,是先执行捕获的,等到冒泡到爷爷身上才执行冒泡阶段的!

    特例:假如被点击的那个元素身上有冒泡和捕获事件,按照代码顺序执行!(也就是说被点击的元素身上没有先捕获后冒泡的顺序之分)

    放一段代码
    var div = document.getElementsByTagName("div");
    div[0].addEventListener('click',function(){
        console.log("爷爷冒泡");
    },false);
    div[0].addEventListener('click',function(){
        console.log("爷爷捕获");
    },true);
    div[1].addEventListener('click',function(){
        console.log("爸爸冒泡");
    },false);
    div[1].addEventListener('click',function(){
        console.log("爸爸捕获");
    },true);
    div[2].addEventListener('click',function(){
        console.log("儿子冒泡");
    },false);
    div[2].addEventListener('click',function(){
        console.log("儿子捕获");
    },true);
    

    点击儿子,看看控制台的打印结果

    image.png


    好了,故事讲完了。

    相关文章

      网友评论

        本文标题:讲个故事,顺便理解DOM事件模型

        本文链接:https://www.haomeiwen.com/subject/lfxziqtx.html