欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解JavaScript中的事件流和事件处理程序

程序员文章站 2022-07-21 18:34:04
事件流:分两种,ie的是 事件冒泡流 ,事件开始时从最具体的元素接收,逐级向上传播到较为不具体的节点(element -> document)。与之相反的是 nets...

事件流:分两种,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级事件处理程序
通过javascript指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序属性。
每个元素都有自己的事件处理程序属性,这些属性通常全部小写,例如onclick。将这种属性的值设置为一个函数,就可以指定事件处理程序。

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

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

dom2级事件处理程序
定义了两个方法,用于处理指定和删除事件处理程序的操作:addeventlistener()和removeeventlistener()。三个参数,1.要处理的事件名。2.作为事件处理程序的函数3.一个布尔值。最后这个布尔值为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);// 移除成功

这两个事件处理程序会按照添加他们的顺序触发。大多数情况,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度的兼容各种版本的浏览器。

优点: 一个元素可以添加多个事件处理程序
缺点: ie8及以下浏览器不支持dom2级事件处理程序。(包括ie8)

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。

跨浏览器的事件处理程序

eg:

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;
    }
  }
}