美文网首页
JS事件顺序(捕获与冒泡)

JS事件顺序(捕获与冒泡)

作者: 明里人 | 来源:发表于2019-12-31 17:45 被阅读0次
问题:

如果一个元素和它的祖先元素注册了同一类型的事件函数(例如点击等), 那么当事件发生时事件函数调用的顺序是什么呢?
比如, 考虑如下嵌套的元素:

<div class="outer">
    <div class="inner"></div>
</div>

两个元素都有onclick的处理函数. 如果用户点击了inner, inner和outer上的事件处理函数都会被调用. 但谁先谁后呢?

事件流:

事件流描述的是从页面中接受事件的顺序,但有意思的是,微软(IE)和网景(Netscape)开发团队居然提出了两个截然相反的事件流概念,IE的事件流是事件冒泡流(event bubbling),而Netscape的事件流是事件捕获流(event capturing)。

事件捕获(event capturing)

网景公司提出的事件流叫事件捕获流。

事件捕获流的思想是不太具体的DOM节点应该更早接收到事件,而最具体的节点应该最后接收到事件,针对上面同样的例子,点击按钮,那么此时click事件会按照这样传播:(下面我们就借用addEventListener的第三个参数来模拟事件捕获流)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <button>
            <p>点击捕获</p>
        </button>
    </div>
    <script>
        var oP=document.querySelector('p');
        var oB=document.querySelector('button');
        var oD=document.querySelector('div');
        var oBody=document.querySelector('body');

        oP.addEventListener('click',function(){
            console.log('p标签被点击')
        },true);
    
        oB.addEventListener('click',function(){
            console.log("button被点击")
        },true);

        oD.addEventListener('click',  function(){
            console.log('div被点击')
        },true);

        oBody.addEventListener('click',function(){
            console.log('body被点击')
        },true);
    </script>
</body>
</html>

同样我们看一下后台的打印结果:


image.png

正如我们看到的,它是和冒泡流万全相反,从最不具体的元素接收到最具体的元素接收事件 body=>div=>button=>p

事件冒泡(event bubbling)

与事件捕获相反, 事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body onclick="bodyClick()">
    <div onclick="divClick()">
        <button onclick="btn()">
            <p onclick="p()">点击冒泡</p>
        </button>
    </div>
    <script>
       function p(){
          console.log('p标签被点击')
       }
        function btn(){
            console.log("button被点击")
        }
         function divClick(event){
             console.log('div被点击');
         }
        function bodyClick(){
            console.log('body被点击')
        }
    </script>
</body>
</html>

点击p元素打印结果:


image.png
DOM事件流:

DOM事件分0级和2级:
1、0级分两种:

  • 行内事件:在标签中写事件
<input type="button" id="btn" value="按钮" onclick="alert('123')">
  • 元素.on事件名=函数
document.getElementById("btn").onclick = function () {
    alert('123');
}
事件没有1级DOM

2、DOM2级事件:添加和移除事件处理程序:addEventListener()和removeEventListener()。

DOM2级(addEventListener)事件流包含3个阶段,事件捕获阶段、处于目标阶段、事件冒泡阶段。 先(document)开始一路向下捕获, 直到达到目标元素, 其后再次从目标元素开始冒泡.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
    <button id="btn">DOM事件流</button>
    <script>
        var btn=document.getElementById("btn");
        btn.onclick=function(event){
            console.log("div 处于目标阶段");
        };
        document.body.addEventListener("click",function(event){
            console.log("event bubble 事件冒泡");
        },false);
        document.body.addEventListener("click",function(event){
            console.log("event catch 事件捕获");
        },true);
    </script>
</body>
</html>

打印结果为:


image.png

就是这样一个流程,先捕获,然后处理,然后再冒泡出去。

作为开发者, 可以决定事件处理器是注册在捕获或者是冒泡阶段. 如果addEventListener的最后一个参数是true, 那么处理函数将在捕获阶段被触发; 否则(false)默认冒泡, 会在冒泡阶段被触发.

阻止冒泡事件:

w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true

参考链接: 浅谈js的事件冒泡和事件捕获

相关文章

  • JS事件顺序(捕获与冒泡)

    问题: 如果一个元素和它的祖先元素注册了同一类型的事件函数(例如点击等), 那么当事件发生时事件函数调用的顺序是什...

  • 事件流 事件监听 (03)

    事件流 从页面接受事件的顺序, 分为 捕获与冒泡 1冒泡 从内往外 (事件的传递) 2捕获 从外往内 (bod...

  • vue 阻止事件冒泡,捕获方法

    要想了解 VUE 阻止事件冒泡和捕获方法,首先要了解一下 JS 事件和 JS 阻止事件冒泡,捕获方法 1. js ...

  • DOM事件流解析

    什么是事件流? 事件流:描述的就是从页面中接受事件的顺序。分有事件冒泡与事件捕获两种。 什么是事件冒泡? 事件冒泡...

  • dom事件捕获与冒泡具体流程

    事件捕获顺序:window--document--html--body--ev 事件冒泡顺序:ev--body--...

  • 事件基础(2)

    js事件的三个阶段:捕获,目标,冒泡 IE:IE事件流是事件冒泡流 Netscape事件流是事件捕获流 IE事件...

  • JS事件相关基础

    js事件: 键盘事件: JS中的事件冒泡和事件捕获: 1、事件冒泡。如下代码: 点击button事件,连同父元素绑...

  • JS-事件捕获和冒泡

    一、事件捕获:事件传递的顺序 (父级到子级)二、事件冒泡:事件处理的顺序 (默认:子级到父级)三、取消冒泡 就...

  • js 阻止冒泡 阻止默认事件

    js冒泡和捕获是事件的两种行为,使用event.stopPropagation()起到阻止捕获和冒泡阶段中当前事件...

  • 默认事件

    js冒泡和捕获是事件的两种行为,使用event.stopPropagation()起到阻止捕获和冒泡阶段中当前事件...

网友评论

      本文标题:JS事件顺序(捕获与冒泡)

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