读《JavaScript高级程序设计》笔记,删除线的地方是对原书的校正,因为书比较旧,具体方法使用时应当再查阅一下文档。
绑定事件监听器(事件处理程序)的方法有4种,第4种仅用于 IE8 及更低版本。
具体实现:通过为HTML元素设置相应特性。特性名为事件监听器的名字(on + 事件名),特性值为能够执行的 js 代码。浏览器内部会为我们绑定的事件处理程序创建一个封装着元素属性值的函数;
点我试试
这种方式添加的事件处理程序会在事件冒泡阶段被处理;
事件对象(event)访问方法:是浏览器内部创建的这个封装函数中的一个局部变量,可以直接在事件处理程序中访问 event 变量;
点我试试
事件处理程序内部的 this:在这个函数内部,this 等于事件的目标元素 绑定当前事件处理程序的元素;
解绑事件的方法:浏览器内部会将为事件处理程序创建的函数赋值给元素上与事件处理程序同名的属性,只要将相应属性赋值为 null 即可。
//以上面代码为例
这个内部创建的函数还有一个特点,就是它会使用 with 语法在内部扩展作用域
function(){
with(document) {
with(this.form) {
with(this) {}
}
}
}
PS:这种事件绑定方法有几个缺点:可能会在尚不具备执行条件的时候触发事件(依赖的 js 文件未加载)、扩展事件处理程序的作用域链的效果在不同浏览器中可能会有差异(在访问一些对象属性时可能导致错误)、使 HTML 代码和 JS 代码紧密耦合。
具体实现:将函数赋值给元素的事件处理程序属性;
这种方式添加的事件处理程序会在事件冒泡阶段被处理;
事件对象(event)访问方法:event 对象可以被作为函数第一个参数传入,也可以直接在函数内部访问 event 变量;
事件处理程序内部的 this:因为事件处理程序是赋值给元素的属性,所以相当于元素的方法,那么事件处理程序就是在元素的作用域中执行的,this 就是该元素的引用(既当前事件处理程序绑定的元素,与第一种绑定方式的 this 相同);
解绑事件的方法:将对应事件处理程序的属性设置为 null 即可。
addEventListener() 文档
removeEventListener() 文档
具体实现:使用 addEventListener() 方法,接受3个参数(要处理的事件名、作为事件处理程序的函数、一个布尔值,这个布尔值为 true 表示在事件捕获阶段调用事件处理程序,为 false 则在事件冒泡阶段调用)。有些浏览器不支持事件捕获(如 IE8 及更低版本),所以谨慎绑定捕获阶段的事件监听器。
事件对象(event)访问方法:event 对象可以被作为函数第一个参数传入,也可以直接在函数内部访问 event 变量(与上一种绑定方法相同);
事件处理程序内部的 this:这里添加的事件处理程序是在调用 addEventListener() 的元素的作用域中执行的,this 就是该元素的引用(既当前事件处理程序绑定的元素,与前两种绑定方式的 this 相同);
解绑事件的方法:通过元素调用 removeEventListener() 来移除,传入的参数与添加事件处理程序时相同,第二个参数(事件处理程序函数)必须是同一个(指向地址相同),所以事件处理程序函数应该保存在一个变量中,传入的是匿名函数则无法移除该事件监听器。
这种绑定方法的优点是可以绑定多个事件处理程序,多个事件处理程序会按照绑定顺序执行。
detachEvent() 文档
具体实现:使用 attachEvent() 方法,接受2个参数(事件处理程序名称、事件处理程序函数),通过该方法绑定的事件处理程序会在冒泡阶段被执行。该方法可以绑定多个事件处理程序,但执行顺序与绑定顺序相反。
事件对象(event)访问方法:event 对象可以被作为函数第一个参数传入,也可以直接在函数内部访问 event 变量(与上一种绑定方法相同);
事件处理程序内部的 this:这里添加的事件处理程序会在全局作用域中运行,与前面的方法都不相同,这里的 this 等于 window;
解绑事件的方法:通过元素调用 detachEvent() 来移除,传入的参数与添加事件处理程序时相同,第二个参数(事件处理程序函数)必须是同一个(指向地址相同),所以事件处理程序函数应该保存在一个变量中,传入的是匿名函数则无法移除该事件监听器。