基本概念
事件就是用户或浏览器自身执行的某种动作,而响应某个事件的函数就叫做事件处理程序。
事件处理程序的名字以“on”开头,例如click
事件的事件处理程序就是onclick
。
HTML 事件处理程序
使用 HTML 属性来指定事件处理程序,这个属性的值要求是能够执行的JavaScript代码。
例子:
<button onclick='console.log("hello")'>OK</button>
在HTML中定义的事件处理程序可以包含需要执行的具体动作,也可以调用在页面其他地方定义的脚本。
例子:
<button onclick='showMessage()'>OK</button>
function showMessage() {
console.log('hello');
};
//输出:hello
在 HTML 中指定事件处理程序有两个缺点:
① HTML与JavaScript代码紧密耦合,如果要更换事件处理程序,就要改动两个地方: HTML代码与JavaScript代码。
②以前面的例子来说明,如果用户在页面解析 showMessage() 函数之前就单击了按钮,就会引发错误,为此,可以把 HTML 事件处理程序封装在try-catch
块中,以便错误不会浮出水面。
例子:
<button onclick='try{showMessage();}catch(ex){}'>OK</button>
function showMessage() {
console.log('hello');
};
//输出:hello
Dom0 级事件处理程序
每个元素(包括 window 和 document)都有自己的事件处理程序属性,例如
onclick
,将这种属性的值设置为一个函数,就可以指定事件处理程序。
例子:
<button id='btn'>OK</button>
var btn = document.getElementById('btn')
btn.onclick = function() {
console.log(this.id);
};
//输出:btn
*使用 Dom0 级方法指定的事件处理程序被认为是元素的方法,因此,这时候的事件处理程序是在元素的作用域中运行,换句话说,程序中的 this 引用当前元素。所以,不仅仅可以取得元素的 ID,实际上可以在事件程序处理中通过 this 访问元素的任何属性和方法。
将事件处理程序属性的值设置为 null ,可以删除事件处理程序,单击按钮不会有任何动作发生。
例子:
<button id='btn'>OK</button>
var btn = document.getElementById('btn')
btn.onclick = function() {
console.log(this.id);
};
btn.onclick = null;
Dom2 级事件处理程序
Dom2 级事件处理程序定义了两个方法,用于指定和删除事件处理程序的操作:
addEventListener()
和removeEventListener()
。所有 Dom 节点都包括这两个方法,并且它们接受三个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值。这个布尔值参数如果是 true,表示在捕获阶段调用事件处理程序;如果是 false(默认值),表示在冒泡阶段调用事件处理程序。
Chrome、FireFox、Opera、Safari、IE9.0及其以上版本都支持这两个方法。
例子:
<button id='btn'>OK</button>
var btn = document.getElementById('btn')
btn.addEventListener('click', function() {
console.log(this.id);
});
//输出:btn
addEventListener()
方法可以给某个元素添加多个相同事件,且不会互相覆盖。
例子:
<button id='btn'>OK</button>
var btn = document.getElementById('btn')
btn.addEventListener('click', function() {
console.log(this.id); //输出:btn
});
btn.addEventListener('click', function() {
console.log('hello'); //输出:hello
});
通过
addEventListener()
添加的事件处理程序只能使用removeEventListener()
来移除,移除时传入的参数和添加程序时的参数相同。这也意味着通过addEventListener()
添加的匿名函数将无法移除。只要能够将对相同函数的引用传给
removeEventListener()
,就可以移除相应的事件处理函数。
例子:
<button id='btn'>OK</button>
var btn = document.getElementById('btn')
var handle = function() {
console.log(this.id);
};
btn.addEventListener('click', handle);
btn.removeEventListener('click', handle);
IE 事件处理程序
IE 实现了与 Dom2 中类似的两个方法:
attachEvent()
和detachEvent()
。这两个方法接受相同的两个参数:事件处理程序名称和事件处理程序函数。IE11+ 中不再支持该方法,因此尽量不要在生产环境中使用,这里只做简单了解即可。
例子:
<button id='btn'>OK</button>
var btn = document.getElementById('btn')
var handle = function() {
alert('hello');
};
btn.attachEvent('onclick', handle);
//输出:hello
通过
attachEvent()
添加的事件处理程序可以使用detachEvent()
来移除,移除时传入的参数和添加程序时的参数相同。这也意味着通过attachEvent()
添加的匿名函数将无法移除。
只要能够将对相同函数的引用传给detachEvent()
,就可以移除相应的事件处理函数。
例子:
<button id='btn'>OK</button>
var btn = document.getElementById('btn')
var handle = function() {
alert('hello');
};
btn.attachEvent('onclick', handle);
btn.detachEvent('onclick', handle);
文章重点
为了保证处理事件的代码能在大多数浏览器下一致,需要自己编写一个跨浏览器的事件处理程序。
代码如下:
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;
}
}
}
文中的代码部分,带有“例子”和“测试代码”字样的,只是用来学习或测试某一功能用的代码,不可以直接用于项目的开发中。带有“代码如下”字样的,都是经过本人测试,简单修改即可用于项目开发中的代码,如有错误,欢迎指出。