JavaScript中addEventListener与attachEvent的区别及事件处理详解
本文详细对比了JavaScript中addEventListener与IE特有的attachEvent方法在参数格式、事件名称及执行顺序上的差异。通过代码实例解析了W3C标准与IE浏览器在事件捕获与冒泡机制上的不同实现,并提供了兼容两种浏览器的通用处理方案及移除事件的正确写法。
addEventListener与attachEvent基本用法对比
在JavaScript中,addEventListener是W3C标准推荐的事件监听方法。
其基本语法为:target.addEventListener(type, listener, useCapture);
其中target代表目标对象,可以是文档节点、document、window或XMLHttpRequest。
type参数为字符串类型的事件名称,不包含前缀“on”,例如“click”、“mouseover”或“keydown”。
listener参数需为实现了EventListener接口的对象,或者是一个普通的JavaScript函数。
useCapture参数用于指定是否使用事件捕获阶段,通常设置为false。例如:document.getElementById("testText").addEventListener("keydown", function (event) { alert(event.keyCode); }, false);
在IE浏览器中:
在Internet Explorer 8及更早版本中,使用的是attachEvent方法进行事件绑定。
其target参数与addEventListener相同,指向文档节点、document、window或XMLHttpRequest。
type参数为字符串类型的事件名称,必须包含前缀“on”,例如“onclick”、“onmouseover”或“onkeydown”。
listener参数同样需为实现了EventListener接口的对象或JavaScript函数。例如:document.getElementById("txt").attachEvent("onclick",function(event){alert(event.keyCode);});
移除事件的方法:removeEventListener与detachEvent
W3C标准及IE浏览器均支持移除已绑定的事件,具体格式如下所示。
W3C标准移除事件的格式为:
W3C标准移除事件的格式为:removeEventListener(event,function,capture/bubble);
在Windows IE浏览器中,移除事件的格式略有不同。
IE移除事件的格式为:detachEvent(event,function);
参数详解与执行优先级差异
再次回顾addEventListener的标准用法:target.addEventListener(type, listener, useCapture);
target参数指定文档节点、document、window或XMLHttpRequest对象。
type参数为不含“on”前缀的事件名称字符串,如“click”、“mouseover”、“keydown”等。
listener参数为实现了EventListener接口的对象或JavaScript函数。
useCapture参数控制是否启用事件捕获,默认为false,具体机制见后续事件流章节。
当事件触发时,浏览器会将一个Event对象传递给事件处理程序。
例如:document.getElementById("testText").addEventListener("keydown", function (event) { alert(event.keyCode); }, false);
需要注意的是,这两种方法适用的浏览器版本不同,实际开发中需进行兼容性处理。
attachEvent方法主要用于IE浏览器中的onclick事件处理。
addEventListener方法则主要适用于Firefox等遵循W3C标准的浏览器中的click事件。
两者的核心区别之一在于绑定多个处理函数时的执行优先级不同,具体见下文实例。
attachEvent方法允许为同一事件附加多个处理函数,但不支持Mozilla系列浏览器。
addEventListener方法则专门用于Mozilla系列及现代标准浏览器。
如果使用直接赋值方式,如:document.getElementById("btn").onclick = method1;
接着赋值:document.getElementById("btn").onclick = method2;
再赋值:document.getElementById("btn").onclick = method3; 则只有method3会被执行,前面的会被覆盖。
若使用attachEvent方法绑定多个函数,代码如下:
var btn1Obj = document.getElementById("btn1"); //object.attachEvent(event,function);
btn1Obj.attachEvent("onclick",method1);
btn1Obj.attachEvent("onclick",method2);
btn1Obj.attachEvent("onclick",method3); 此时执行顺序为method3->method2->method1,即后绑定的先执行。
Mozilla系列浏览器不支持attachEvent,需使用addEventListener。var btn1Obj = document.getElementById("btn1");
//element.addEventListener(type,listener,useCapture);
btn1Obj.addEventListener("click",method1,false);
btn1Obj.addEventListener("click",method2,false);
btn1Obj.addEventListener("click",method3,false); 此时执行顺序为method1->method2->method3,即先绑定的先执行。
兼容IE与Firefox的完整实例代码
以下是一个完整实例:(注意HTML中的div元素必须位于JavaScript代码之前)。
具体代码如下:
<html>
<head>
</head>
<body>
<div id="name1" style="border:1px solid red;padding:10px 10px 10px 10px;" style="border:1px solid red;padding:10px 10px 10px 10px;">
<div id="name2" style="border:1px solid green;padding:10px 10px 10px 10px;" style="border:1px solid green;padding:10px 10px 10px 10px;">点击</div>
</div>
<div id="info"></div>
<script type="text/javascript"><!--
var name1=document.getElementById('name1'); //要注意
var name2=document.getElementById('name2'); //要注意
var info=document.getElementById('info');
if(name1.attachEvent){ //对于attachEvent前面的target我们一定要保证不为空
name1.attachEvent('onclick',function () { info.innerHTML += "红色" + "<br>"; });
name2.attachEvent('onclick',function () { info.innerHTML += "绿色" + "<br>"; });
}else{
name1.addEventListener('click',function () { info.innerHTML += "红色" + "<br>"; },false);
name2.addEventListener('click',function () { info.innerHTML += "绿色" + "<br>"; },false);
}
// --></script>
</body>
</html>DOM0与DOM2事件模型演进
从W3C的发展时间轴来看,DOM(Document Object Model)模型主要分为DOM 0和DOM 2两个阶段。从版本号即可看出,DOM 0是较旧的协议,具体对比见下表。
DOM1协定主要定义了基础事件属性。
|
Event Name |
Description |
|
onblur() |
The element has lost focus (that is, it is not selected by the user). |
|
onchange0 |
The element has either changed (such as by typing into a text field) or the element has lost focus. |
|
onclick0 |
The mouse has been clicked on an element. |
|
ondblclick() |
The mouse has been double-clicked on an element. |
|
onfocus() |
The element has gotten focus. |
|
onkeydown() |
A keyboard key has been pressed down (as opposed to released) while the element has focus. |
|
onkeypress() |
A keyboard key has been pressed while the element has focus. |
|
onkeyup() |
A keyboard key has been released while the element has focus. |
|
onload() |
The element has loaded (document, frameset, or image). |
|
onmousedown() |
A mouse button has been pressed. |
|
onmousemove() |
The mouse has been moved. |
|
onmouseout() |
The mouse has been moved off of or away from an element. |
|
onmouseover() |
The mouse has moved over an element. |
|
onmouseup() |
A mouse button has been released. |
|
onreset() |
The form element has been reset, such as when a form reset button is pressed. |
|
onresize() |
The window's size has been changed. |
|
onselect() |
The text of a form element has been selected. |
|
onsubmit() |
The form has been submitted. |
|
onunload() |
The document or frameset has been unloaded. |
DOM2在事件处理上进行了进化,引入了更灵活的事件监听机制。
|
DOM 0 Event |
DOM 2 Event |
|
onblur() |
blur |
|
onfocus() |
focus |
|
onchange() |
change |
|
onmouseover() |
mouseover |
|
onmouseout() |
mouseout |
|
onmousemove() |
mousemove |
|
onmousedown() |
mousedown |
|
onmouseup() |
mouseup |
|
onclick() |
click |
|
ondblclick() |
dblclick |
|
onkeydown() |
keydown |
|
onkeyup() |
keyup |
|
onkeypress() |
keypress |
|
onsubmit() |
submit |
|
onload() |
load |
|
onunload() |
unload |
事件捕获与冒泡机制解析
通过新的DOM2用法,可以使用addEventListener()函数来观察事件处理。
其语法为:addEventListener(event,function,capture/bubble);
参数event对应上述表格,function为要执行的函数,capture与bubble分别代表W3C制定的两种事件模式。简单来说,capture模式从document开始一直读取到最后一行再执行事件;而bubble模式则是先定位到指定元素位置再执行事件。capture/bubble参数为布尔值,True表示使用capture,False则是bubble。Windows Internet Explorer也制定了一种EventHandler,即attachEvent(),格式如下:
window.attachEvent(”submit”,myFunction());
图像Rollover综合示例
值得注意的是,attachEvent不需要指定capture/bubble参数,因为在Windows IE环境下默认均使用Bubble模式。这里通过图像的Rollover例子来展示事件的具体用法:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd“> <html> <head> <title>Rollover</title> <script type=”text/javascript”>function moveOver(imgObj) { if (typeof window.addEventListener != “undefined”) { imgObj.addEventListener(”mouseover”,function(){imgObj.src = imgObj.id + “_over.png”;}, false); imgObj.addEventListener(”mouseout”, function(){imgObj.src = imgObj.id + “_default.png”;}, false); } else { imgObj.attachEvent(”onmouseover”,function(){imgObj.src = imgObj.id + “_over.png”;}); imgObj.attachEvent(”onmouseout”, function(){imgObj.src = imgObj.id + “_default.png”;}); } }
function rollover() { var images = document.getElementsByTagName(”img”); var roll = new RegExp (”rollover”); var preload = []; for (var i = 0; i < images.length; i++) { if (images[i].id.match(roll)) { preload[i] = new Image(); preload[i].src = images[i].id + “_over.png”; moveOver(images[i]); } } } if (typeof window.addEventListener != “undefined”) { window.addEventListener(”load”,rollover,false); } else { window.attachEvent(”onload”,rollover) } </script> </head> <body> <p><img id=”rollover_home” name=”img_home” src=”rollover_home_default.png” alt=”Home”></p> <p><img id=”rollover_about” name=”img_about” src=”rollover_about_default.png” alt=”About”></p> <p><img id=”rollover_blog” name=”img_blog” src=”rollover_blog_default.png” alt=”Blog”></p> <p><img id=”logo” name=”img_logo” src=”logo.png” alt=”Braingia Logo”></p> </body> </html>
上述代码中 typeof window.addEventListener != “undefined” 用于判断用户浏览器是否支持AddEventListener事件模型,如果不支持则回退使用attachEvent。
移除事件的兼容写法
W3C标准及IE浏览器同时支持移除指定的事件,其用途是移除之前设定的事件,具体格式分别如下:
W3C标准移除事件的格式为:
removeEventListener(event,function,capture/bubble);
Windows IE浏览器移除事件的格式如下:
detachEvent(event,function);
数据参考来源:Chapter 14 - Browsers and JavaScript, JavaScript Step by Step, by Steve Suehring
D3.js 处理大规模数据点的性能优化策略
2026-11-05 15:37:25
JS实现网页摄像头实时扫码:结合getUserMedia与jsQR教程
2026-11-05 15:27:28
D3.js v5 迁移到 v7 的 API 变更与注意事项
2026-11-05 11:57:17
使用 animate.js 实现多元素协同的序列动画
2026-11-04 22:27:53
JS拖拽排序时怎么添加平滑动画效果?FLIP技术实战
2026-11-04 10:12:22
