您的位置:首页 > 其它

Dojo学习--event(2): 事件指派和对象方法

2017-03-25 12:44 501 查看
继续学习Dojo的事件机制:

事件指派(Event Delegation)

NodeList 的on函数可以给一串DOM节点赋值handler事件处理函数。dojo/on也通过事件指派来实现这个功能

事件指派的意思:

不对每一个DOM元素都指定事件处理函数,而是给DOM树中尽量最高级别的元素上指定一个事件处理函数。按照事件冒泡原理,低级别的DOM元素的事件会传递到高级别DOM元素上。这个高级别的DOM元素会检查捕获到的事件,只要判断传递来的事件的属于哪个子元素,然后去做相应的子元素的处理。

事件指派的好处是

1,减少事件处理程序的数量,提升页面的性能:每个函数都是对象,都会占用内存,所以事件处理程序的数量关系到整个页面的运行性能。

2,减少对DOM元素的访问次数:每个定义的事件处理程序都会绑定到DOM元素上,也就有对DOM元素的访问。减少事件处理程序的数量,一定程度上减少对DOM元素的访问。

适合事件指派的事件:

适合采用事件指派技术的事件包括click, mousedown, mousup, keydown, keyup, keypress。虽然mouseover和mouseout事件也冒泡,但是处理它们并不容易,而且经常需要计算它们的位置。

之前的dojo版本dojox/Nodelist/delegate 会实现这个事件委托,现在依然有用。1.10版本开始,也可以用dojo/on 模块来实现相关功能,使用on函数语法:

**on(parent element, "selector:event name",handler)**


例子如下:

<div id="parentDiv">
<button id="button1" class="clickMe">Click me</button>
<button id="button2" class="clickMe">Click me also</button>
<button id="button3" class="clickMe">Click me too</button>
<button id="button4" class="clickMe">Please click me</button>
</div>
<script>
require(["dojo/on", "dojo/dom", "dojo/query", "dojo/domReady!"],
function(on, dom){

var myObject = {
id: "myObject",
onClick: function(evt){
alert("The scope of this handler is " + this.id);
}
};
var div = dom.byId("parentDiv");
on(div, ".clickMe:click", myObject.onClick);

});
</script>


查看运行结果: 事件指派例子–运行结果

注意:1,使用中,仍然需要dojo/query模块,即使我们不会直接使用到模块功能。因为 dojo/on需要dojo/query的选择引擎去匹配dom元素而指派事件。

2,上述例子也能说明一个问题,事件指派设计中,事件处理关注并不是高级别元素(也可以称之为父级元素),虽然这个元素作为第一个参数传递到on中。事件指派的处理函数关注的是处理匹配的子元素的操作。

对象方法

dojo/on的“前任”dojo.connect, 负责方法到方法的事件链接。这个功能已经单独成一个模块:dojo/aspect.

Publish/Subscribe

之前的例子处理的情况是:已知一个对象以及已知其要做event处理。但是,如果在你不知道一个节点对象要处理什么event的时候(也许可以理这个理解:只知道这个节点要进行和某个已知对象的event操作一样,至于具体事件处理程序不知道),或者甚至不知道何时这个对象会被创建。这种情况下,你需要Dojo 的dojo/topic模块的publish与subscribe (pub/sub)。

这个框架是1.10开始引入。Pub/sub允许注册一个处理函数handler(通过subscribe) 到一个 topic,这个topic其实是事件别名的string形式。这个事件可以拥有多种资源,被多个节点使用。当这个topic被publish时handler会被调用。

pub/sub适用场景:

当你开发一个应用时,希望有个按钮去提现用户操作。我们不想重复开发,这个小功能又不值得包装成对象。

通过以下例子更深一步理解pub/sub

<button id="alertButton">Alert the user</button>
<button id="createAlert">Create another alert button</button>

<script>
require(["dojo/on", "dojo/topic", "dojo/dom-construct", "dojo/dom", "dojo/domReady!"],
function(on, topic, domConstruct, dom) {

var alertButton = dom.byId("alertButton"),
createAlert = dom.byId("createAlert");

on(alertButton, "click", function() {
// When this button is clicked,
// publish to the "alertUser" topic
topic.publish("alertUser", "I am alerting you.");
});

on(createAlert, "click", function(evt){
// Create another button
var anotherButton = domConstruct.create("button", {
innerHTML: "Another alert button"
}, createAlert, "after");

// When the other button is clicked,
// publish to the "alertUser" topic
on(anotherButton, "click", function(evt){
topic.publish("alertUser", "I am also alerting you.");
});
});

// Register the alerting routine with the "alertUser" topic.
topic.subscribe("alertUser", function(text){
alert(text);
});

});
</script>


查看运行结果:对象事件例子–运行结果

这种模式的事件写法使得事件处理与事件对象解耦,这样有一个优点:不需要创建DOM元素,就可以进行单元。若不想再保持一个主题,topic.subscribe返回一个对象,这个对象有一个remove方法,这个方法可以移除相应事件处理(与on函数类似)。

注意: 不同于dojo.publishtopic.publish参数不需要写成数组形式。以下两种写法是相等的,注意参数的不同写法:

topic.publish("someTopic", "foo", "bar")
dojo.publish("someTopic", ["foo", "bar"]).


Dojo事件总结

dojo事件机制很强大,也很容易使用。on方法屏蔽了浏览器之前的不一致。pub/sub框架中,dojo/topic给出了一种解绑事件处理程序与事件对象的方法。需要多花时间去熟悉这些工具,相信在web应用的构建中还是很有益处的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dojo pub-sub 事件指派