JavaScript 事件流与冒泡机制详解

作者:窗边听雨

时间:2026-10-25

浏览:204

本文深入解析 JavaScript 事件传播机制,区分捕获型与冒泡型事件的不同执行路径。通过具体示例展示如何利用 addEventListener 控制事件阶段,并提供兼容 IE 与非 IE 浏览器的阻止冒泡代码实现,同时梳理事件监听函数的使用差异及事件对象的获取方式。

文章目录
事件流

JavaScript 事件流基础

JavaScript 中的事件传播表现为一种流的形式,多个元素可以同时响应同一事件。


但在实际开发中,往往希望仅由特定元素处理绑定的事件,而非所有祖先节点。



事件分类

捕获型与冒泡型事件机制

事件传播分为两种模式:捕获型事件(主要见于非 IE 浏览器)和冒泡型事件(所有浏览器均支持)。




捕获型事件自上而下传播,而冒泡型事件自下而上回溯。具体流程可通过图示直观理解:


JavaScript 事件流基础

工作中常见的是冒泡型事件,若需触发非 IE 浏览器中的捕获型事件,



只需在调用 addEventListener 时将第三个参数设置为 true 即可启用捕获阶段。



具体示例如下:Link


JavaScript 事件流基础

假设 div1 和 div2 两个元素均绑定了捕获阶段的事件处理函数,


此时点击 #div1(蓝色区域),预期会弹出提示“div1”。


若点击 #div2(黄色区域),由于捕获阶段事件从根元素向下传播,且 #div1 是 #div2 的父元素,因此会先弹出“div1”,随后再弹出“div2”,即 #div1 上的 click 事件先于 #div2 执行。


冒泡事件示例与阻止方法

以下是冒泡型事件的示例:


相关代码如下:

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>冒泡事件</title>
<script type="text/javascript">
var i = 1;
function Add(sText,objText)
{ 
document.getElementById("Console").innerHTML +=sText + "执行顺序:" + i + "<br />" + "<hr />";
i = i + 1;
//window.event.cancelBubble = true;
} 
</script>
</head>
<body onclick="Add('body事件触发<br />','body')">
<div onclick="Add('div事件触发<br />','div')">
<p onclick="Add('p事件触发<br />','p')" style="background:#c00;">点击</p>
</div>
<div id="Console" style="border:solid 1px #ee0; background:#ffc;"></div>
</body>
</html>

从该示例可清晰观察到,事件冒泡过程是从目标元素 P 一直向上传递至 body 元素。




阻止事件冒泡



以下函数实现了对 IE 及其他浏览器的兼容,用于阻止事件冒泡:


相关代码如下:

 
function stopBubble(e) {
//如果提供了事件对象,则这是一个非IE浏览器
if ( e && e.stopPropagation )
//因此它支持W3C的stopPropagation()方法
e.stopPropagation();
else
//否则,我们需要使用IE的方式来取消事件冒泡
window.event.cancelBubble = true;
} 

在 IE 浏览器中并未提供 stopPropagation 方法,但可通过设置 window.event.cancelBubble 为 true 来阻止冒泡。




事件监听函数与对象获取

监听函数


IE 浏览器使用 attachEvent 和 detachEvent。



非 IE 浏览器使用 addEventListener 和 removeEventListener。



除上述四个方法外,还有一种通用方式:document.getElementById(元素ID).onclick = function(){}。




事件对象


在触发事件时,如何在监听函数内部获取事件对象?在 IE 中通过 window.event.srcElement 获取,而在非 IE 浏览器中则使用 e.currentTarget。



示例代码:


相关代码如下:

 
btn.onclick = ctdClickEvent;
function ctdClickEvent(e)
{ 
if( !-[1,] ) //IE
{ 
var readonly = "readOnly";
var obj = window.event.srcElement;
}else{ //非IE
var readonly = "readonly";
var obj = e.currentTarget;
} 
var id = obj.id.replace("btn_","");
if( obj.value=="此项改为不续费" )
{ 
...... 
}else{
....... 
} 
sumPrice();
} 

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章