当前位置 : 主页 > 网络编程 > JavaScript >

带你彻底搞懂JavaScript的事件流

来源:互联网 收集:自由互联 发布时间:2023-01-18
目录 DOM事件流 事件冒泡 事件捕获 情景一:直接在HTML中绑定事件 情景二:[domNode].onclick()方式DOM0级 情景三:[domNode].addEventListener()方式DOM2级 总结 DOM事件流 要明白事件流,首先我们要
目录
  • DOM事件流
    • 事件冒泡
    • 事件捕获
    • 情景一:直接在HTML中绑定事件
    • 情景二:[domNode].onclick()方式——DOM0级
    • 情景三:[domNode].addEventListener()方式——DOM2级
  • 总结

    DOM事件流

    要明白事件流,首先我们要明白三点:

    • 元素不是独立的,是串联在一起的
    • 单个元素触发事件以后还会影响其他元素
    • 事件流的方式:事件捕获(网景提出)、事件冒泡(IE提出)

    在这里插入图片描述

    我们就以上图为例,假设你给div绑定了点击事件,当你点击了div后,其他元素也会受之牵连,会引起牵一发而动全身的效果

    事件流的方式有两种:事件冒泡事件捕获

    事件冒泡

    在这里插入图片描述

    事件冒泡阶段:在点击完div后立即触发目标事件,然后再一层一层向上冒泡

    事件捕获

    在这里插入图片描述

    事件捕获阶段:在点击完div后不会立即触发div的事件,而是一层一层向下捕获,最终到达div才触发事件。

    其实,这两种阶段,在日后的项目开发中都有可能遇见,因为不同的绑定事件方法,造就了不同的事件阶段(冒泡/捕获)

    情景一:直接在HTML中绑定事件

    <body onclick="console.log('我是body')">
        <button onclick="console.log('我是button')">
            <span onclick="console.log('我是span')">快乐按钮</span>
        </button>
    </body>
    

    效果:

    请添加图片描述

    从上图可看出,当我们点击span标签以后,上层button身上的事件以及body身上的事件都会按冒泡顺序执行

    情景二:[domNode].onclick()方式 —— DOM0级

    html:

    <body>
        <button>
            <span>快乐按钮</span>
        </button>
    </body>
    

    javascript:

    var body = document.getElementsByTagName('body')[0];
    var button = document.getElementsByTagName('button')[0];
    var span = document.getElementsByTagName('span')[0];
    body.onclick = function() {console.log('我是body')};
    button.onclick = function() {console.log('我是button')};
    span.onclick = function() {console.log('我是span')};
    

    效果:

    请添加图片描述

    我们发现,DOM0级绑定事件的方式依然是冒泡的形式

    情景三:[domNode].addEventListener()方式 —— DOM2级

    addEvenListener(事件名,事件触发后的回调,布尔值)

    false(默认):表示在冒泡阶段调用事件处理程序true:表示在捕获阶段调用事件处理程序

    html:

    <body>
        <button>
            <span>快乐按钮</span>
        </button>
    </body>
    

    javascript:

    var body = document.getElementsByTagName('body')[0];
    var button = document.getElementsByTagName('button')[0];
    var span = document.getElementsByTagName('span')[0];
    function theName() {console.log('我是' + this.nodeName)};
    body.addEventListener('click',theName,false);
    button.addEventListener('click',theName,false);
    span.addEventListener('click',theName,false);
    

    效果:

    请添加图片描述

    我们可以看到当addEventListener的第三个参数为false(不写默认也是false)的时候,事件流为冒泡。

    当我们把第三个参数改为true时:

    ......
    body.addEventListener('click',theName,true);
    button.addEventListener('click',theName,true);
    span.addEventListener('click',theName,true);
    

    请添加图片描述

    我们发现,执行顺序为body ——> button ——> span,为事件捕获阶段。

    DOM2级规定:

    • 事件流包括三个阶段(1.捕获阶段 2.目标阶段 3.冒泡阶段)
    • 执行循序应遵循:捕获阶段 ——> 目标阶段 ——> 冒泡阶段

    也就是说当你点击目标元素后,不会立刻执行触发事件,而是先执行事件捕获阶段 ——> 然后处于目标阶段(触发事件) ——> 事件冒泡阶段

    我们来看一道经典面试题:当我们点击baby婴儿时的输出顺序?

    在这里插入图片描述

    html:

    <body>
        <div class="grandma">grandma奶奶
            <div class="mother">mother妈妈
                <div class="daughter">daughter
                    <div class="baby">baby婴儿</div>
                </div>
            </div>
        </div>
    </body>
    

    javascript:

    var grandma = document.getElementsByClassName('grandma')[0]
    var mother = document.getElementsByClassName('mother')[0]
    var daughter = document.getElementsByClassName('daughter')[0]
    var baby = document.getElementsByClassName('baby')[0]
    function theName() {
        console.log('我是' + this.className);
    }
    baby.addEventListener('click', theName, false)//冒泡
    daughter.addEventListener('click', theName, true)//捕获
    mother.addEventListener('click', theName, true)//捕获
    grandma.onclick = theName//冒泡
    

    结果:

    在这里插入图片描述

    做题思路:

    • 先给绑定好事件的元素划分是 捕获?冒泡?我们可以看到daughtermother捕获babygrandma冒泡
    • 因为DOM2规定先捕获后冒泡,因此会先打印daughter和mother其中之一
    • 因为捕获是从上至下(dom根——>div),因此先打印mother后daughter
    • 因为冒泡是从下至上(div——>dom根),因此打印baby后再打印grandma

    总结

    本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注自由互联的更多内容!  

    上一篇:JavaScript的事件监听你了解吗
    下一篇:没有了
    网友评论