手记

JavaScript事件处理程序

基本概念

事件就是用户或浏览器自身执行的某种动作,而响应某个事件的函数就叫做事件处理程序。
事件处理程序的名字以“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;
        }
    }
}

文中的代码部分,带有“例子”和“测试代码”字样的,只是用来学习或测试某一功能用的代码,不可以直接用于项目的开发中。带有“代码如下”字样的,都是经过本人测试,简单修改即可用于项目开发中的代码,如有错误,欢迎指出。

2人推荐
随时随地看视频
慕课网APP