【译】addEventListener 第二个参数
这是原文链接:Our Backwards DOM Event Libraries
浏览器APIs
先简单回顾一下各个浏览器提供了哪些绑定事件的接口。
IE浏览器提供了element.attachEvent接口,可以绑定事件到元素上面。
document.body.attachEvent(
'onclick',
function() {
alert('body clicked');
});
其他浏览器则提供了element.addEventListener接口,我们比较熟悉的是绑定一个函数到元素上。
document.body.addEventListener(
'click',
function() {
alert('body clicked');
},
false);
许多javascript程序员还不知道其实还可以传递一个object给addEventListener当作第二个参数,当事件被触发时,该object的handleEvent方法被调用。
document.body.addEventListener(
'click',
{
handleEvent: function() {
alert('body clicked');
}
},
false);
使用object作为第二个参数有一个重要的特征:handleEvent属性的函数值只会在事件触发的时候会被调用。这意味着我们改变handleEvent属性的函数值,那么事件触发时就会调用不同的函数,也就是延迟绑定。举个例子:
var obj = {};
document.body.addEventListener('click', obj, false);
// click body will error in some browsers because
// no handleEvent method on obj
obj.handleEvent = function() {alert('alpha');};
// click body and see alert "alpha"
obj.handleEvent = function() {alert('beta');};
// click body and see alert "beta"
document.body.removeEventListener('click', obj, false);
// click body and see nothing
跨浏览器的库
我们实现跨浏览器的应用时,不应该因为不同浏览器的混乱的APIs写出糟糕而重复的代码,有一个好主意就是抽象出不同的APIs,实现我们自己的事件库。
不同的库有不同的APIs,但是每个库都有一个类似下面的接口:
LIB_addEventListener(
document.body,
'click',
function() {
alert('body clicked');
});
关于javascript中this的技巧
这些库都有一个常见的问题:如果事件触发,我们调用的是视图对象的一个方法就会有问题。举个例子,比如下面的代码。handleClick方法中this的值是window对象。所以alert会显示undefined,而不是我们期待的alpha。
function ViewObject() {
this.data = 'alpha';
LIB_addEventListener(
document.body,
'click',
this.handleClick);
}
ViewObject.prototype.handleClick = function() {
alert(this.data);
};
这些库中已经给出了解决办法,就是指定一个额外的参数作为this的值。这同样有利于解除事件监听。举例如下,alert会显示alpha。
function ViewObject() {
this.data = 'alpha';
LIB_addEventListener(
document.body,
'click',
this.handleClick,
this);
}
ViewObject.prototype.handleClick = function() {
alert(this.data);
};
ViewObject.prototype.destroy = function() {
LIB_removeEventListener(
document.body,
'click',
this.handleClick,
this
);
};
目前的API仍然有一个隐藏的问题:当LIB_addEventListener被调用时,监听函数就已经被绑定了。这时如果我们改变handleClick的函数值并且尝试删除监听函数,就会遇到问题。
var vo = new ViewObject();
// click on the body and see alert "alpha"
vo.handleClick = function() {
alert('beta');
};
// click on the body and still see "alpha"
vo.destroy();
// click on the body and still see "alpha"!
还有一个问题就是我们采用面向对象的方式编程,但是我们却在关注listener functions而不是listener objects。这种不匹配是寻找更优解的线索。
适配listener objects的API
由于我们经常采用面向对象的方式来编程,所以很有必要让LIB_addEventListener可以接受listener objects(当然也接受listener functions)
var obj = {
handleEvent: function() {
alert('click handler');
}
};
LIB_addEventListener(document.body, 'click', obj);
通常我们会有一个视图对象来处理各种元素的多种事件。不过需要第四个参数来指定方法名称。这仍然可以实现延迟绑定。
var obj = {
handleMouseDown: function() {
alert('mouse down handler');
},
handleMouseUp: function() {
alert('mouse up handler');
}
};
LIB_addEventListener(document.body, 'mousedown', obj, 'handleMouseDown');
LIB_addEventListener(document.body, 'mouseup', obj, 'handleMouseUp');
通过判断第三个参数的类型,该API仍然可以接收listener functions。
LIB_addEventListener(document.body, 'mousedown', function() {
alert('mousedown');
});
不过我们已经没有必要使用listener functions了,因为还需要多此一举指定this object。我们可以直接使用更好的listener object。
以上内容纯属翻译
【译】addEventListener 第二个参数的更多相关文章
- addEventListener调用带参数函数
当传递参数值时,使用"匿名函数"调用带参数的函数: <body> <button id="btn">click me</butto ...
- 关于replace()方法中第二个参数的转义问题
如果你想通过Javascript代码在网页中呈现 \ 字符,则在JS代码中你必须输入两个反斜杠 \\,否则会报错.比如: var a = "\"; alert(a); //chro ...
- 字符串正则替换replace第二个参数是函数的问题
按照JS高程的说法,如下 replace()方法的第二个参数也可以是一个函数.在只有一个匹配项(即与模式匹配的字符串)的情况下,会向这个函数传递3个参数:模式的匹配项.模式匹配项在字符串中的位置和原始 ...
- 学习 Message(5): 关于 TApplicationEvents.OnMessage 的第二个参数 可以屏蔽 TWebBrowser右键菜单:
http://www.cnblogs.com/del/archive/2008/10/25/1319318.html TApplicationEvents.OnMessage 的第二个参数 Handl ...
- parseInt第二个参数详解
前阵子在stackOverflow上看到两个这样的问题: 为什么parseInt(8,3) == NaN,parseInt(16,3) == 1? 为什么parseInt('dsff66',16) = ...
- 关于字符串replace方法第二个参数探究
网上有关replace的文章很多了,这里主要聊聊它的第二个参数.阅读本文需要对replace方法有一定了解.W3school=>replace 我们要把一段字符串中的某些指定字符替换掉,第一时间 ...
- IE6/7/8中parseInt第一个参数为非法八进制字符串且第二个参数不传时返回值为0
JavaScript中数字有十进制.八进制.十六进制.以"0"开头的是八进制,"0x"或"0X"开头的是十六进制. parseInt用来把字 ...
- ***php解析JSON二维数组字符串(json_decode函数第二个参数True和False的区别)
客户端的请求体中的数据:[{"msg_id": 1, "msg_status": "HAS_READ" }, { "msg_id& ...
- Listen第二个参数的意义
今天主要回顾下listen的第二个参数的意义. 话说现在现在都是用框架写业务代码.真的很少在去关注最基本的socket函数的意义了.该忘得都忘得差不多了.~~~ 要慢慢捡起来. 主要是在看redi ...
随机推荐
- Python新手学习基础之数据结构-序列2
长度.最大值和最小值 序列类型的数据结构,常常会用到长度检查.最大最小值检查的函数. 他们的作用: len(序列):返回列表的长度(元素个数): max(序列) :返回列表中元素最大值: min(序列 ...
- C语言初学 数组 打印菱形
#include<stdio.h> #include<stdlib.h> int main() { int n,i,j; printf("---开始打印符号--\n& ...
- Swift互用性: 使用Objective-C特性编写Swift类(Swift 2.0版)-b
本节包括内容: 继承Objective-C的类(Inheriting from Objective-C Classes) 采用协议(Adopting Protocols) 编写构造器和析构器(Writ ...
- Android Service 启动和停止服务
activity_main.xml 定义两个Button控件,start_service和stop_service. <LinearLayout xmlns:android="http ...
- RUBY,玩玩~~~
我觉得吧,这东瀛的红宝石,也得玩玩,毕竟,RUBY ON RAILS,PUPPET等也是一股力量. 作为混IT圈的,知道总没坏处. 就是感觉和C,C++,JAVA,C#,PHP,甚至PYTHON的感觉 ...
- h.264 fast,1/2,1/4像素运动估计与插值处理
Hadamard Transform 在1/2,1/4像素运动估计这一阶段中,对于像素残差,可以选择采用哈达玛变换来代替离散余弦变换进行高低频的分离. 优点:哈达玛矩阵全是+1,-1,因此只需要进行加 ...
- HDU 2444 The Accomodation of Students(判断是否可图 + 二分图)
题目大意:有一群人他们有一些关系,比如A认识B, B认识C, 但是这并不意味值A和C认识.现在给你所有互相认识的学生,你的任务是把所有的学生分成两个一组, 住在一个双人房里.相互认识的同学可以住在一个 ...
- LVS安装配置
LVS安装部署 一.LVS安装(CENTOS) 1.LVS模块ip_vs已经内置在LINUX内核中,一般情况下ip_vs并没有启动,可以通过lsmod | grep ip_vs查看,能够看到信息表示模 ...
- delphi 通过控件的handle取得控件
例子代码如下: vartsg:TstringGrid;begintsg:=Tstringgrid(FindControl(handle));//正常使用TstringGrid//tsg......./ ...
- Android Studio 首次安装报错 Java.lang.RuntimeException:java.lang.NullPointerException...错
下次安装报:Java.lang.RuntimeException: java.lang.NullPointerException......错 只需在文件..\Android Studio\bin\i ...