引用说明:原文来自于http://coralsea.bokee.com/viewdiary.12065264.html,为了方便本人阅读,文本格式略有调整。
本文档目标:
1、简单介绍Dojo的事件处理框架——Event System。
2、这样的事件处理框架对于页面内的组件解耦是有帮助的。
Dojo Event System
Dojo的Event System以类似于AOP的advice机制的风格,来为DOM事件和任何的方法提供统一的事件处理框架,而不会给使用大多数简单的DOM事件机制的开发者带来额外的学习和开发负担。
Dojo关注的事件不仅仅是DOM事件,它把任何的JS方法调用都看作可以侦听的事件。
参见:The Dojo Event System
事件绑定示例:
1.简单的示例代码:
场景:当按钮点击事件发生时,调用handleOnClick方法。
var buttonNode = document.getElementById(“button”);
function handleOnClick(evt)
{
……
}
dojo.event.connect(buttonNode,”onclick”,”handleOnClick”);
这样当按钮的点击事件时间发生时,handleOnClick方法也就会被调用。
2. 普通的事件绑定代码:
场景:如果按钮的点击事件发生,则调用object的handle方法。
以前我们这么写:
var buttonNode= document.getElementById("button");
buttonNode.onclick = function(evt){
object.handler(evt);
};
现在Dojo将其简化成:
var buttonNode = document.getElementById("button");
dojo.event.connect(buttonNode, "onclick", object, "handler");
3. 多个事件的绑定
var buttonNode = document.getElementById("button");
dojo.event.connect(buttonNode, "onclick", object1, "handler1");
dojo.event.connect(buttonNode, "onclick", object2, "handler2");
这样当按钮点击事件发生时,就会先调用object1的handle1方法,再调用object2的handle2方法。
4. 解除绑定
可以使用Dojo的disconnect方法,调用参数与connect一致,即可解除之前的绑定操作。
5. 关键字绑定
为了防止不经意间对事件的多处绑定,造成连锁调用。Dojo提供关键字链绑定,比如可以只绑定一次:
dojo.event.kwConnect({
srcObj: exampleObj,
srcFunc: "foo",
targetObj: exampleObj,
targetFunc: "bar",
once: true
});
同样,对应也提供了一个kwDisconnect()方法来进行关键字绑定的解除。
6. 延迟执行和循环执行的绑定
Dojo同样可以通过关键字绑定来使方法延迟执行或者循环执行。
7. 高级应用:Seeking Advice
除了提供上述的后次序绑定,还可以提供before的绑定,这有点类似于AOP的逻辑。
提供around advice方式,解决场景:
如果待绑定的源方法和目的方法的签名不一样;
如果想改变代码的行为,但是又不改写代码。
around advice可以包装任何方法,然后操纵方法的输入和输出。
代码示例如下:
function foo(arg1, arg2){
// …
}function aroundFoo(invocation){
if(invocation.args.length < 2){
// note that it's a real array, not a pseudo-arr
invocation.args.push("default for arg2");
}
var result = invocation.proceed();
// we could change the result here
return result;
}dojo.event.connect("around", "foo", "aroundFoo");
这样,当foo方法只传入一个参数的时候,aroundFoo方法会为其添加第二个参数,然后继续foo方法的执行。
8. 通过Topic机制来注册和订阅事件
示例代码如下:
var exampleObj = {
counter: 0,
foo: function(){
alert("foo");
this.counter++;
},
bar: function(){
alert("bar");
this.counter++;
}
};
// previously we used this connect syntax
//
// dojo.event.connect(exampleObj, "foo", exampleObj, "bar");
//// which we now replace with:
// set up our publisher
dojo.event.topic.registerPublisher("/example", exampleObj, "foo");// and at some point later, register our listener
dojo.event.topic.subscribe("/example", exampleObj, "bar");
工作的基本原理:
通过在JavaScript中动态改变方法名称,使用apply方法来实现对方法的顺序绑定。
基本原理代码:
var global = this;
function naiveConnect(funcName1, funcName2){
global["__prefix"+funcName1] = funcName1;
global[funcName1] = function(){
global["__prefix"+funcName1].apply(global, arguments);
global[funcName2].apply(global, arguments);
}
}