JavaScript中addEventListener与attachEvent的区别及事件处理详解

作者:像素漫游

时间:2026-10-23

浏览:75

本文详细对比了JavaScript中addEventListener与IE特有的attachEvent方法在参数格式、事件名称及执行顺序上的差异。通过代码实例解析了W3C标准与IE浏览器在事件捕获与冒泡机制上的不同实现,并提供了兼容两种浏览器的通用处理方案及移除事件的正确写法。

文章目录
在Mozilla浏览器中:

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

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章