function Button(value,domEl){
this.domEl=domEl;
this.value=value;
this.domEl.onclick=this.clickHandler;
}
继续定义一个事件处理函数作为Button类的一部分。
Button.prototype.clickHandler=function(){
alert(this.value);
}
这段代码看起来很直观,但是它并没有做我们希望它做的事情。警告框通常会返回消息unde- fined,而不是传递到构造函数的value属性。为什么呢?当点击DOM元素时,函数click- Handler由浏览器调用,它设置函数上下文到DOM元素,而不是Button的JavaScript对象。于是,this.value指向DOM元素的value属性,而不是Button对象的value属性。你永远也不可能通过查看事件处理函数的声明来发现这个情况,是不是?
我们可以通过向DOM元素传递Button对象的引用来解决这个问题,也就是,按下面的方法修改构造函数:
function Button(value,domEl){
this.domEl=domEl;
this.value=value;
this.domEl.buttonObj=this;
this.domEl.onclick=this.clickHandler;
}
DOM元素仍然没有value属性,但是它有一个到Button对象的引用,可以从那里得到value。通过对事件处理函数做如下修改,我们的工作就完成了:
Button.prototype.clickHandler=function(){
var buttonObj=this.buttonObj;
var value=(buttonObj && buttonObj.value) ?
buttonObj.value : "unknown value";
alert(value);
}
DOM节点引用Button对象,Button对象引用它的value属性,这样事件处理函数就做了我们希望它做的事情。我们可以直接给DOM节点附加value,不过附加一个指向整个后端对象的引用可以使这种模式容易地用于任意复杂的对象,顺便说一句,我们在这里已经实现了一个小的MVC模式,其中DOM元素作为后端对象模型的前端视图。
以上讨论的就是传统的事件模型。这种事件模型主要的缺点是每个元素只允许有一个事件处理函数。在第3章介绍的Observer模式中,我们注意到一个可观察的元素在给定时间可以有任意多个观察者附加在上面。当为Web页面编写简单的脚本时,这可能不会成为一个严重的缺点,但是当迈向更加复杂的Ajax客户端的时候,我们开始感觉到了更多的限制。我们将在4.3.3节中更为密切地考察这个问题,现在来看看新近出现的事件模型。
[1] [2]