1.引言
在本篇博客中主要介绍一下Dojo中的事件机制,以及如何给DOM结点绑定事件,我们也是介绍一下Dojo的发布订阅模式publish/subscribe
。
2.Dojo中的鼠标事件绑定
在Dojo中鼠标事件的绑定机制有两种:
on
类型的事件绑定(借助于dojo/on
模块)connect
类型的事件绑定(借助于dojo.connect
方法)
dojo的事件绑定机制屏蔽了浏览器的差异,所以我们使用dojo给DOM元素绑定事件可以应用于所有浏览器当中。
2.1 on
类型的事件绑定
首先我们先看一下on
类型的事件是如何绑定的。主要是对dojo/on
模块的使用。
- 首先我们定义一个
button
<button id="btn">Click me!</button>
- 给该按钮绑定事件(通过字符串形式)
require(["dojo/on", "dojo/dom","dojo/domReady!"],
function(on, dom) {
//获得dom元素
var btn= dom.byId("btn")
//给DOM元素绑定事件
on(btn, "click", function(evt){
alert("按钮被点击了");
});
})
- 注意:并不是所有的浏览器支持
"click"
字符串绑定的方式,所以dojo提供了一个扩展模块,dojo/mouse
提供了对IE7以及IE8的支持。
require(["dojo/on","dojo/dom","dojo/mouse", "dojo/domReady!"],
function(on, dom, mouse) {
var btn= dom.byId("btn");
on(btn, mouse.enter, function(evt){
alert("按钮被点击了")
});
});
2.2 模块dojo/on
介绍
在上面我们已经简单的使用的dojo/on
模块绑定了一个事件,在上面我们使用的方法为:on(element,event.name,handler)
element
为DOM元素event.name
为事件名称handler
为事件处理函数
上面我们只是介绍了dojo/on模块最简单的使用,接下来我们看一下dojo/on
模块中其他方法的使用。
- 我们利用
dojo/on
给自己的对象绑定事件(注意:自己定义的类必须继承dojo/Evented
模块)
require(["dojo/on","dojo/dom","dojo/_base/declare","dojo/Evented","dojo/domReady!"],
function(on, dom,declare,Evented) {
//定义一个obj对象(注意:类继承了Evented模块)
var myclass=declare([Evented],{
});
var obj=new myclass();
//给obj绑定一个myevent事件
on(obj,"myevent",function(param){
alert(param.key);
});
on(dom.byId("btn"),"click",function(){
//触发事件,并且传参
on.emit(obj,"myevent",{key:"事件被触发了"})
})
});
2.3如何解绑事件(on
方式解绑事件)
当我们使用dojo/on
模块绑定事件时,会返回一个事件句柄,我们可以通过该句柄解绑事件,代码如下:
//handle为事件句柄
var handle = on(btn, "click", function(evt){
//解绑事件,事件只调用一次
handle.remove();
alert("事件被触发了,但是只调用一次");
});
2.4使用connect方式绑定事件
在dojo/on模块出现之前,我们一直使用dojo.connect
方法绑定事件,不过现在这种绑定事件的方式已经逐渐被淘汰了,在这里只是简单的介绍一下如何使用该方法,绑定事件
require(["dojo/dom","dojo/domReady!"],
function(dom) {
var btn=dom.byId("btn");
dojo.connect(btn,"onclick",function()
{
alert("我被点击了")
})
});
2.5 如何解绑事件(connect方式解绑事件)
require(["dojo/dom","dojo/domReady!"],
function(dom) {
var btn=dom.byId("btn");
var handle=dojo.connect(btn,"onclick",function()
{
//解绑事件
dojo.disconnect(handle);
alert("我被点击了")
})
});
2.6 如何阻止事件传递
什么是事件传递,我们先来举个例子
- 创建两个标签(div里面有btn)
<div id="mydiv">
<button id="btn">click me!</button>
</div>
- 然后我们给div和button都绑定事件
require(["dojo/dom","dojo/on","dojo/domReady!"],
function(dom,on) {
var btn=dom.byId("btn");
var div=dom.byId("mydiv");
on(div,"click", function (evt) {
alert("div被点击了")
})
on(btn,"click", function (evt) {
alert("btn被点击了")
})
});
- 当我们点击按钮的时候(btn事件被触发,div的事件也被触发了),这是因为btn在div里面,所以事件传播了。
- 如何阻止事件向上冒泡,使用evt对象的
stopPropagation
方法,代码如下:
require(["dojo/dom","dojo/on","dojo/domReady!"],
function(dom,on) {
var btn=dom.byId("btn");
var div=dom.byId("mydiv");
on(div,"click", function (evt) {
alert("div被点击了")
})
on(btn,"click", function (evt) {
alert("btn被点击了")
//阻止事件的向上传播
evt.stopPropagation();
})
});
2.7 阻止按钮的默认事件
- 使用evt的
preventDefault
方法,例如submit
按钮有默认提交表单的事件,我们就可以使用这个方法阻止。
3.发布/订阅模式
在上面的例子中,我们使用dojo/on绑定事件,然而事件的触发是由系统触发的,也就是说事件的触发我们几乎不可控(给自定义对象绑定自定义事件除外)。在dojo中,dojo提供了一个发布订阅模式,我们可以利用发布订阅模式,实现一些更加复杂的功能,使用发布订阅模式我们可以控制事件何时触发,发布订阅模式在面向对象中还存在这一些更加高级的作用。
3.1 最简单的发布订阅模式
- 创建一个按钮
<button id="btn1">绑定订阅</button>
<button id="btn2">发布订阅</button>
- js代码实现发布订阅模式
require(["dojo/dom","dojo/on","dojo/topic","dojo/domReady!"],
function(dom,on,topic) {
var btn1=dom.byId("btn1");
var btn2=dom.byId("btn2");
on(btn1,"click", function () {
//绑定订阅
topic.subscribe("mytopic",function(param){
alert(param)
});
})
on(btn2,"click", function () {
//也就是触发事件,后面是传入的参数
topic.publish("mytopic",["a","b"])
});
});
3.2 如何移除订阅事件
require(["dojo/dom","dojo/on","dojo/topic","dojo/domReady!"],
function(dom,on,topic) {
var handle;
var btn1=dom.byId("btn1");
var btn2=dom.byId("btn2");
on(btn1,"click", function () {
//绑定订阅
handle=topic.subscribe("mytopic",function(param){
alert(param)
//只是触发一次;解除绑定
handle.remove();
})
})
on(btn2,"click", function () {
//也就是触发事件,后面是传入的参数
topic.publish("mytopic",["a","b"])
})
});
4.总结
在本篇博客中主要介绍了Dojo中的事件机制是如何实现的,主要写了如何去给自己的DOM元素绑定事件,如何利用on给自己定义的对象绑定自定义的事件,然后又简单的介绍了一下发布订阅模式。其中如果给自己定义的对象自定义对象,和发布订阅模式很重要,在Dojo的面向对象思想中尤为重要。