JavaScript事件流详解:冒泡、捕获及阻止机制

作者:交互手记

时间:2026-10-30

浏览:160

本文详细解析JavaScript中的事件流机制,涵盖IE提出的事件冒泡与Netscape提出的事件捕获。通过示例演示如何触发事件,并重点讲解使用stopPropagation()阻止冒泡以及利用DOM3级新增的stopImmediatePropagation()方法阻止捕获的技巧,帮助开发者掌握事件处理的核心控制手段。

文章目录

事件流概述

事件流描述了页面中接收事件的传播顺序。这一概念由IE和Netscape分别提出,其中IE主张的是广泛使用的事件冒泡流,而Netscape则提出了事件捕获流。

事件冒泡机制

第一部分:事件冒泡

事件冒泡指的是事件最初由最具体的目标元素接收,随后逐级向上传播至不太具体的节点,直至文档对象。

下面通过一个简单示例进行说明:


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>bubble</title>
  <style>
    button{
      background: red;
      color:white;
    }
    #third{
      width: 50px;
      height: 50px;
      border:thin solid red;
    }
    #second{
      width: 100px;
      height: 100px;
      border:thin solid red;
    }
    #first{
      width:200px;
      height: 200px;
      border:thin solid red;
    }
  </style>
</head>
<body>
  <div id="first">
    <div id="second" >
      <div id="third" >
        <button id="button">事件冒泡</button>
      </div>
    </div>
  </div>
  <script>

    document.getElementById("button").addEventListener("click",function(){
      alert("button");
    },false);

    document.getElementById("third").addEventListener("click",function(){
      alert("third");
    },false);

    document.getElementById("second").addEventListener("click",function(){
      alert("second");
    },false);    

    document.getElementById("first").addEventListener("click",function(){
      alert("first");
    },false);

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

此时,仅点击button元素,运行效果如下:

事件流概述

结果显示,尽管仅点击了button,但其外层的third、second和first元素上的事件由内向外依次触发。触发顺序从DOM树底层向顶层进行,因此被称为冒泡。

(注:即便此处使用DOM0级事件处理程序,结果依然相同,冒泡是默认行为;此处虽设置DOM2级事件处理程序为冒泡阶段,但结论一致。)

若不希望事件发生冒泡,应如何阻止?

实际上,事件对象提供了stopPropagation()方法用于阻止冒泡。只需将上述示例中button的事件处理程序修改为如下代码:


    document.getElementById("button").addEventListener("click",function(event){
      alert("button");
      event.stopPropagation();  
    },false);

修改后,点击button仅会弹出一个显示“button”的提示框。

注意:现代所有浏览器均支持事件冒泡,尽管具体实现存在差异。

事件捕获机制

第二部分:事件捕获

事件捕获与冒泡过程相反,它指不太具体的节点应更早接收事件,而最具体的目标节点最后接收。示例如下:


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>bubble</title>
  <style>
    button{
      background: red;
      color:white;
    }
    #third{
      width: 50px;
      height: 50px;
      border:thin solid red;
    }
    #second{
      width: 100px;
      height: 100px;
      border:thin solid red;
    }
    #first{
      width:200px;
      height: 200px;
      border:thin solid red;
    }
  </style>
</head>
<body>
  <div id="first">
    <div id="second" >
      <div id="third" >
        <button id="button">事件冒泡</button>
      </div>
    </div>
  </div>
  <script>

    document.getElementById("button").addEventListener("click",function(){
      alert("button");
    },true);

    document.getElementById("third").addEventListener("click",function(){
      alert("third");
    },true);

    document.getElementById("second").addEventListener("click",function(){
      alert("second");
    },true);    

    document.getElementById("first").addEventListener("click",function(){
      alert("first");
    },true);

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

在此例中,仅将addEventListener()方法的第三个参数由之前的false改为true,即采用捕获方式获取button事件,结果如下:

事件流概述

可见最外层事件最先触发,最后才是被点击的button事件,这便是事件捕获机制。

若要阻止事件捕获,使用stopPropagation()方法吗?答案是否定的。需明确,stopPropagation()仅能阻止冒泡,无法阻止捕获。

但可使用DOM3级新增的stopImmediatePropagation()方法来阻止捕获,该方法同样能阻止冒泡。应用如下:


document.getElementById("second").addEventListener("click",function(){

  alert("second");

  event.stopImmediatePropagation();

},true);   

如此,即可在id为second的元素处阻止事件捕获。

注意:虽然事件流模型由Netscape Navigator提出,且现代浏览器均支持,但因旧版浏览器不支持,故实际应用中较少使用事件捕获。

DOM事件流三阶段

第三部分:DOM事件流

DOM2级规范规定的事件流包含三个阶段:

  • 事件捕获阶段
  • 处于目标阶段
  • 事件冒泡阶段

注意:在DOM事件流中,实际目标在捕获阶段不接收事件,随后进入处于目标阶段(此时事件被触发),最后进入冒泡阶段。通常认为处于目标阶段属于冒泡阶段的一部分。

以上为本文全部内容,希望对学习有所帮助,欢迎支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章