DOM事件流之事件捕获与冒泡

149 阅读2分钟

DOM事件流(event flow )分为以下三个阶段:

事件捕获阶段
事件捕获(event capturing):意思是当鼠标点击或者触发dom事件的时候,浏览器会从这个事件的元素根节点开始一层一层的传播至当前元素,即我们触发了这个元素,如果它的父元素通过事件捕获方式注册了对应的事件的话,会先触发父元素绑定的事件。
处于目标阶段
事件到达目标节点时,就到了目标阶段,事件在目标节点上被触发
事件冒泡阶段
事件冒泡(dubbed bubbling):与事件捕获恰恰相反,事件冒泡顺序是由内到外进行事件传播,直到根节点,也就是说从目前元素开始一级一级往上进行事件传播。

不支持冒泡的事件有

  • UI事件
    load, unload,scroll,resize
  • 焦点事件
    blur, focus
  • 鼠标事件
    mouseleave, mouseenter**

支持冒泡的事件有

  • 点击事件
    click ,dbclick ,
  • 键盘事件
    keydown ,keyup ,
  • 鼠标事件
    mousedown ,mousemove ,mouseout ,mouseover ,mouseup ,scroll

在如下结构中

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件冒泡与捕获示例</title>
    <style>
        #parent {
            padding: 20px;
            background-color: lightblue;
        }
        #child {
            padding: 10px;
            background-color: coral;
        }
        #output {
            margin-top: 20px;
            white-space: pre-wrap; /* 保持换行 */
        }
    </style>
</head>
<body>

<div id="parent">
    <button id="child">点击我</button>
</div>
<pre id="output"></pre>

<script>
    const output = document.querySelector("#output");

    // 事件冒泡示例
    function parentClick() {
        output.textContent += "父元素被点击(冒泡)\n";
    }
    function childClick() {
        output.textContent += "子元素被点击(冒泡)\n";
    }
    // 在父,子元素上添加点击事件处理器(冒泡)
    document.getElementById("parent").addEventListener("click", parentClick);
    document.getElementById("child").addEventListener("click", childClick);

    // 事件捕获示例
    function parentClickCapture() {
        output.textContent += "父元素被点击(捕获)\n";
    }
    function childClickCapture() {
        output.textContent += "子元素被点击(捕获)\n";
    }
    // 在父,子元素上添加捕获阶段的点击事件处理器
    document.getElementById("parent").addEventListener("click", parentClickCapture, true);
    document.getElementById("child").addEventListener("click", childClickCapture, true);
</script>

</body>
</html>

addEventListener方法的第三个参数useCapture(通常称为truefalse)用于指定事件处理程序是在事件的捕获阶段还是在冒泡阶段执行。

当我们点击按钮时,输出将显示:

捕获.PNG

  • 首先,捕获阶段的事件处理程序被调用,从父元素开始,然后是子元素。
  • 接着,目标元素(子元素)的冒泡阶段处理程序被调用,然后是父元素的冒泡阶段处理程序。

dom标准事件流的触发的先后顺序为:先捕获再冒泡,即每当我们进行事件触发的时候,先进行捕获事件的触发,再进行冒泡。目前除IE10及以下不支持捕获型事,其他浏览器如IE11、Chrome 、Firefox、Safari等浏览器则同时存在。