详解JavaScript事件流与三种事件处理程序

作者:流萤

时间:2026-10-30

浏览:137

本文深入解析JavaScript中的事件流机制,包括IE的事件冒泡与Netscape的事件捕获。详细对比DOM0级、DOM2级(addEventListener)及IE特有的attachEvent三种事件处理程序的实现方式、触发顺序及优缺点,并提供跨浏览器兼容的事件处理方案。

文章目录

JavaScript事件流机制

事件流主要分为两种模式:IE浏览器采用的事件冒泡流,其机制是事件从最具体的目标元素开始接收,随后逐级向上传播至较不具体的节点(即从Element向Document传播);而Netscape浏览器则采用相反的事件捕获流。

根据DOM2级事件规范,完整的事件流包含三个连续阶段:首先是事件捕获阶段,接着是处于目标阶段,最后是事件冒泡阶段。

在实际开发中,通常建议将事件处理程序绑定到事件流的冒泡阶段。以下是一个EventUtil工具类的示例代码。


var EventUtil = {
  addHandler: function(element, type, handler){
    if(element.addEventListener){
      element.addEventListener(type, handler, false);
    }else if(element.attachEvent){
      element.attachEvent('on' + type, handler); // IE8
    }else{
      element['on' + type] = handler;
    }
  },
  removeHandler: function(){...}
}

接下来我们将对各类事件处理程序进行详细解析。

DOM0级事件处理程序

DOM0级事件处理程序:这是通过JavaScript指定事件处理程序的传统方式,具体做法是将一个函数赋值给元素的事件处理程序属性。每个元素都拥有自己的事件处理程序属性,这些属性名通常全部小写,例如onclick。只需将该属性的值设置为一个函数,即可为元素指定对应的事件处理程序。


var btn = document.getElementById('myBtn');
// 添加事件处理程序
btn.onclick = function () {
  alert( this );//为DOM元素btn
};
// 移除事件处理程序
btn.onclick = null;

优点:1.简单2.具有跨浏览器的优势 缺点:在代码运行之前不会指定事件处理程序,因此这些代码在页面中位于按钮后面,就有可能在一段时间怎么点击都没反应,用户体验变差。

DOM2级事件处理程序

DOM2级事件处理程序:该规范定义了两个核心方法,用于执行指定和移除事件处理程序的操作,分别是addEventListener()和removeEventListener()。这两个方法均接收三个参数:第一个是要处理的事件类型名称;第二个是作为事件处理程序的函数;第三个是一个布尔值,当该值为true时,表示在捕获阶段调用事件处理程序,为false时则表示在冒泡阶段调用。


// 添加多个事件处理程序
var btn = document.getElementById('myBtn');
btn.addEventListener('click',function (){
  alert( this );// 为DOM元素btn
},false );
btn.addEventListener('click',function () {
  alert('Hello World');
},false);

// 移除事件处理程序
btn.removeEventListener('click',function () {
  // 匿名函数无法被移除,移除失败
},false);
  // 改写
  var handler = function () {
  alert(this.id);
  };
  btn.addEventListener('click',handler,false);
  // 再次移除事件处理程序
  btn.removeEventListener('click',handler,false);// 移除成功

通过DOM2级方法添加的多个事件处理程序,会严格按照它们被添加的顺序依次触发。鉴于大多数情况下建议将事件处理程序添加到冒泡阶段,这种做法能够最大限度地兼容各种版本的浏览器。

DOM2级事件处理程序的优点在于允许为一个元素添加多个事件处理程序。其主要缺点是不兼容IE8及更低版本的浏览器(包含IE8)。

IE事件处理程序

IE事件处理程序:IE浏览器定义了两个类似的方法,分别为attachEvent()和detachEvent()。这两个方法接收两个参数:事件处理程序名称和事件处理程序函数。由于IE8及更早版本的浏览器仅支持事件冒泡机制,因此通过detachEvent()移除的事件处理程序实际上是从冒泡阶段中移除的。


var btn = document.getElementById('myBtn');
btn.attachEvent('onclick', function(){
  alert( this );// window
});
btn.attachEvent('onclick', funciton(){
  alert("HELLO, WORLD");
});

在IE浏览器中,点击按钮时这两个事件处理程序的触发顺序与前述DOM2级机制恰好相反。它们并非按照添加事件处理程序的顺序触发,而是以相反的顺序执行。

IE事件处理程序的优点同样是一个元素可以添加多个事件处理程序。其显著缺点是仅支持IE浏览器,缺乏跨浏览器兼容性。

跨浏览器事件处理方案

为了实现跨浏览器的事件处理,需要封装统一的处理逻辑。

以下是一个跨浏览器事件处理程序的示例代码,展示了如何兼容不同浏览器的事件绑定与移除操作。


var EventUtil = {
  addHandler : function ( ele, type, handler ) {
    if ( ele.addEventListener ) {
      ele.addEventListener( type, handler, false );
    } else if ( ele.attachEvent ) {
      ele.attachEvent( 'on' + type, handler );
    } else {
      ele['on' + type] = handler
    }
  },
  removeHandler: function ( ele, type, handler ) {
    if ( ele.removeEventListener ) {
      ele.removeEventListener( type, handler, false );
    } else if ( ele.detachEvent ) {
      ele.detachEvent( 'on' + type, handler );
    } else {
      ele[ 'on' + type ] = null;
    }
  }
}

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章