事件处理程序即给元素绑定事件的方式有下列几种:HTML事件处理程序、DOM0级事件处理程序、DOM2级事件处理程序、IE事件处理程序、跨浏览器事件处理程序。其实这些方式就是一个逐步优化和实现跨浏览器的过程。
1、HTML事件处理程序:直接在html的标签中添加事件属性,例如:
<div οnclick="fun()"></div>
这样做很是不好,有下列两大缺点,这也是如今在开发中很难见到这样绑定事件的原因。
(1)存在一个时差问题,因为用户可能会在HTML元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件(比如js代码还没有下载下来),由此会引发错误。
(2)HTML与js代码紧密耦合。如果要更换事件处理程序,就要改动两个地方:HTML代码和JS代码,这非常不利于后期代码的维护。
所以这种方法在开发中基本不用,但是还是得了解它是怎么个用法和为什么不用它的原因。
2、DOM1级事件处理程序:将一个函数赋值给一个事件处理程序属性,表示元素的方法,这时的事件处理程序是在元素的作用域中运行。例如:
var oBox = document.getElementById("container");
oBox.onclick = function() {}
这种做法的优点是:简单和所有浏览器都支持。
缺点是:只能给该元素绑定一个事件。于是出现DOM2级事件处理程序。
3、DOM2级事件处理程序:addEventListener()添加事件,removeEventListener()删除事件。可添加多个,执行顺序与添加顺序相同。两个方法都接受三个参数:
第一个参数:事件名称
第一个参数:作为事件处理程序的函数
第一个参数:捕获值false(不捕获)/true(捕获),不写表示默认值false
例如:
var oBox = document.getElementById("container");
oBox.addEventListener("click",fn(),false);
oBox.removeEventListener("click",fn(),false);
function fn(){//执行代码}
关于第三个参数一般填写默认值false或不填,因为:大多数情况下,都是将事件处理程序添加到时间流的冒泡阶段,这样可以最大限度地兼容各种浏览器,如果不是特别需要,不建议在事件捕获阶段注册事件处理程序。关于捕获和冒泡同时存在的情况下我总结了以下几点:
(1)冒泡且捕获:捕获导致不能进入更低层事件,点击该层的更低层只能触发该捕获层,一般为了不阻断其他事件的触发设置捕获为false。
(2)冒泡但不捕获:执行冒泡顺序,从触发层从内到外执行事件,与事件监听绑定的顺序无关。
(3)若多级包含元素且多个元素都添加事件监听则为了更稳定的执行时间需要:①每个元素的事件监听的捕获都设置为false或不填。②并且在执行函数内阻止冒泡。e.stopPropagation()||e.cancelBubble=true;
4、IE事件处理程序:attachEvent()添加事件,detachEvent()删除事件,由于(IE8-)不支持捕获,所以两种方法只支持两个参数:
第一个参数:事件处理程序函数名称eg:onclick onmouseover
第二个参数:作为事件处理程序的函数
例如:
var oBox = document.getElementById("container");
oBox.attach("click",fn());
oBox.detach("click",fn());
function fn(){//执行函数}
注意:使用这种方法的事件处理程序的作用域是全局,函数内this指向window而不是事件目标对象,如果要指定事件目标对象可以也使用event.srcElement。能给添加多个,但是执行顺序与添加顺序相反。
5、跨浏览器事件处理程序:
var EventUtil = {
addHandle: function(element,type,handle) {
if(element.addEventListener) {
element.addEventListener(type,handle);
}else if(element.attachEvent) {
element.attachEvent("on"+type,handle);
}else {
element["on"+type] = handle;
}
},
removeHandle: function(element,type,handle) {
if(element.removeEventListener) {
element.removeListener(type,handle);
}else if(element.detachEvent) {
element.detachEvent("on"+type,handle);
}else {
element["on"+type] = null;
}
}
}
EventUtil.addHandle(oBox,"click",fn);
EventUtil.removeHandle(oBox,"click",fn);