代码改变世界

学习javascript中的事件——事件处理程序

2016-03-29 15:51  ARMdong  阅读(249)  评论(0编辑  收藏  举报

  事件就是用户或浏览器自身执行的某种动作。诸如 click、load 和 mouseover ,都是事件的名字。而响应某个事件的函数就叫做事件处理程序(或事件侦听器)。事件处理程序的名字以“on”开头,因此click事件的事件处理程序就是onclick,load事件的事件处理程序就是onload。为事件指定处理程序的方式有好几种。

 

一、DOM0 级事件处理程序

1、指定事件处理程序:以“on”开头,后面接事件名称,然后把一个匿名函数表达式或者函数作为属性值赋值给这个属性,就为这个元素指定了时间处理函数。

示例代码:

html:

<div id="div1"></div>

 

javascript:

var oDiv = document.getElementById('div1');
oDiv.onclick = function(){
    console.log("Clicked !");
};

 

2、删除事件处理程序:将事件处理程序属性的值设置为null就可以删除该元素的该事件的处理程序。

oDiv.onclick = null;

 

 

二、DOM2 级事件处理程序

  “DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener() 和 removeEventListener()。所有DOM节点中都包含这两个方法,并且它们都接受3个参数:要处理的事件名(不带“on”)、作为事件处理程序的函数和一个布尔值。最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

 

1、指定事件处理程序:addEventListener()

var oDiv = document.getElementById('div1');
oDiv.addEventListener("click", function(){
    console.log(this.id);
}, false);

 

  上面的代码为div添加了 onclick 事件处理程序,而且该事件会在冒泡阶段被触发(因为最后一个参数是false)。与DOM0级方法一样,这里添加的事件处理程序也是在其依附的元素的作用域中运行。使用 DOM2 级方法添加事件处理程序的主要好处是可以添加多个事件处理程序。看看下面的例子:

var oDiv = document.getElementById('div1');
oDiv.addEventListener("click", function(){
    console.log(this.id);
}, false);
oDiv.addEventListener("click", function(){
    console.log("Hello World !");
}, false);

  这里为oDiv的 onclick 事件添加了两个事件处理程序,在点击oDiv的时候这两个事件处理都会被触发,而且触发的顺序和定义的顺序保持一致。依次是弹出oDiv的id属性值和“Hello World !”。

  

2、移除事件处理程序:removeEventListener()

  使用addEventListener()添加的事件处理程序只能通过removeEventListener()来移除;移除时传入的参数与添加处理程序时使用的参数相同。这也意味着通过 addEventListener() 添加的匿名函数将无法移除,如下面的例子:

var oDiv = document.getElementById('div1');
oDiv.addEventListener("click", function(){
    console.log(this.id);
}, false);

// 省略其它代码

oDiv.removeEventListener("click", function(){
    console.log(this.id);
}, false);

  在这个例子中,我们使用了 addEventListener() 添加了一个事件处理程序。虽然调用了 removeEventListener() 时看似使用了相同的参数,但实际上,第二个参数与传入 addEventListener() 中的那一个是完全不同的函数。而传入 removeEventListener() 中的事件处理程序函数必须与传入 addEventListener() 中的相同,如下面的例子所示:

var oDiv = document.getElementById('div1');
var handler = function(){
    console.log(this.id);
};
oDiv.addEventListener("click", handler, false);

// 省略其它代码

oDiv.removeEventListener("click", handler, false);

 

  重写后的这个例子没有问题,是因为在 addEventListener() 和 removeEventListener() 中使用了相同的函数。

  注意:最后需要注意的点是在大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度地兼容各种浏览器。最好只在需要在事件到达目标之前截获它的时候将事件处理程序添加到捕获阶段。如果不是特别需要,我们不建议在事件捕获阶段注册事件处理程序。

  IE9、Firefox、Safari、Chrome 和 Opera 支持 DOM2 级事件处理程序。

 

三、IE 事件处理程序

  IE 中指定和移除事件处理程序的两个方法分别是:attachEvent() 和 DetachEvent()。这两个方法接受相同的两个参数:事件处理程序和事件处理程序函数。由于 IE8 及之前的IE版本之支持事件冒泡,所以通过 attachEvent() 添加的事件处理程序都会被添加到事件流的冒泡阶段。

1、指定事件处理程序:attachEvent()

  要使用 attachEvent() 为oDiv添加一个事件处理程序,可以使用下面这段代码:

var oDiv = document.getElementById("div1");
oDiv.attachEvent("onclick", function(){
    console.log("Clicked !");
});

 

  使用 attachEvent() 指定事件处理程序的时候需要注意的是传入的第一个参数是“onclick”, 而不是DOM2级事件中 addEventListener() 方法中的“click”。

  与DOM0级方法的区别:在 IE 中使用 attachEvent() 与使用 DOM0 级方法的主要区别在于事件处理程序的作用域。在使用 DOM0 级方法的情况下,事件处理程序会在其所属元素的作用域内运行;在使用 attachEvent() 方法的情况下,事件处理程序会在全局作用域中运行,因此此时的 this 等于 window。来看下面的例子:

var oDiv = document.getElementById("div1");
oDiv.attachEvent("onclick", function(){
    console.log(this === window); // true
});

  attachEvent() 方法与 addEventListener() 方法类似,attachEvent() 方法也可以为一个元素添加多个事件处理程序。看看下面的例子:

var oDiv = document.getElementById("div1");
oDiv.attachEvent("onclick", function(){
    console.log("Clicked !"); 
});
oDiv.attachEvent("onclick", function(){
    console.log("Hello World !"); 
});

  这段代码调用了两次 attachEvent() 方法,为同一个元素添加了两个不同的事件处理程序。不过,与 addEventListener() 不同的是,这些事件处理程序不是以添加他们的顺序执行,而是以相反的顺序被触发。单击这个例子中的oDiv,首先看到的是"Hello World !" ,然后才是"Clicked !"。

2、移除事件处理程序: detachEvent()

  使用 attachEvent() 方法添加的事件处理程序只能通过 detachEvent() 方法来移除,条件和DOM2级事件处理程序一样,必须提供相同的参数。也就是说通过 attachEvent() 方法添加的匿名函数将不能被移除。下面来看看移除事件处理程序的例子:

var oDiv = document.getElementById("div1");
var handler = function(){
    console.log("Clicked !");
};
oDiv.attachEvent("onclick", handler);

// 省略其它代码

oDiv.detachEvent("onclick", handler);

 

注意:IE11 中不支持 attachEvent() 和 detachEvent() 方法为元素指定和移除事件处理程序。

 

四、跨浏览器的事件处理程序

  为了兼容不同浏览器支持的事件处理程序的差异,下面编写一个简单的事件处理程序js工具类:

var EventUtil = {

    addHandler = function(element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent("on"+type, handler);
        } else {
            element["on" + type] = handler;
        }
    },
    removeHandler = function(element, type, handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent("on"+type, handler);
        } else {
            element["on" + type] = null;
        }
    }

};

  使用这个工具类中的 addHandler() 和 removeHandler() 方法为元素指定和移除事件处理程序的时候,首先会检查元素支不支持 DOM2 级方法,如果支持就使用 DOM2 级方法。如果不支持的话再检查是不是IE浏览器,如果是则使用IE中的方法,如果不是就使用 DOM0 级方法。不过在使用 DOM0 级方法指定事件处理程序的时候只能为元素指定一个事件处理函数,如果指定多个,后添加的会覆盖前面添加的事件处理程序。