JavaScript 事件流与冒泡机制详解
本文深入解析 JavaScript 事件传播机制,区分捕获型与冒泡型事件的不同执行路径。通过具体示例展示如何利用 addEventListener 控制事件阶段,并提供兼容 IE 与非 IE 浏览器的阻止冒泡代码实现,同时梳理事件监听函数的使用差异及事件对象的获取方式。
JavaScript 事件流基础
JavaScript 中的事件传播表现为一种流的形式,多个元素可以同时响应同一事件。
但在实际开发中,往往希望仅由特定元素处理绑定的事件,而非所有祖先节点。
事件分类
捕获型与冒泡型事件机制
事件传播分为两种模式:捕获型事件(主要见于非 IE 浏览器)和冒泡型事件(所有浏览器均支持)。
捕获型事件自上而下传播,而冒泡型事件自下而上回溯。具体流程可通过图示直观理解:

工作中常见的是冒泡型事件,若需触发非 IE 浏览器中的捕获型事件,
只需在调用 addEventListener 时将第三个参数设置为 true 即可启用捕获阶段。
具体示例如下:Link

假设 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();
} anime.js 快速入门:怎么引入库并编写第一个 DOM 动画
2026-11-05 14:22:43
在线JS解密后变量名仍乱码?结合浏览器DevTools调试还原
2026-11-04 20:26:01
怎么在浏览器中运行JavaScript代码并查看输出结果
2026-11-04 09:07:33
JS 获取屏幕分辨率:window.screen.width 与 height 用法
2026-11-04 08:52:48
为什么推荐用DOMContentLoaded代替window.onload初始化JS
2026-11-04 08:42:33
