Dojo学习笔记(五):Dojo的事件机制

前端之家收集整理的这篇文章主要介绍了Dojo学习笔记(五):Dojo的事件机制前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1、DOM事件

Dojo 的主要的DOM事件处理机制是dojo/on。Dojo为用户提供了统一的DOM事件机制,通过使用Dojo的dojo/on,用户可以避免各种DOM API的分歧,同时DOJO也预防了内存泄露问题。

页面on.HTML代码如下:

效果:当点击按钮时,div变成蓝色,单鼠标经过div时,div变成红色,当鼠标离开后,div变成白色。

<!DOCTYPE html>
<html>
<head lang="en">
    <Meta charset="UTF-8">
    <title></title>
    <style>
        #myButton {
            margin-bottom:1em;
        }
        #myDiv {
            border: 1px solid black;
            background-color: white;
            width: 100px;
            height: 100px;
        }
    </style>
    <script src="dojo/dojo.js" data-dojo-config="async: true"></script>
    <script>
        require(["dojo/on","dojo/dom","dojo/dom-style","dojo/mouse","dojo/domReady!"],function(on,dom,domStyle,mouse) {
                    var myButton = dom.byId("myButton"),myDiv = dom.byId("myDiv");
                    on(myButton,"click",function(evt){
                        domStyle.set(myDiv,"backgroundColor","blue");
                    });
                    on(myDiv,mouse.enter,"red");
                    });
                    on(myDiv,mouse.leave,"");
                    });
                });
    </script>
</head>
<body>
<button id="myButton">Click me!</button>
<div id="myDiv" style="background-color: red; ">Hover over me!</div>
</body>
</html>

注意:dojo/mouse是必须的,并不是所有的浏览器都支持mouseenter和mouseleave事件,dojo/mouse添加了这样的支持

on(element,event name,handler),这种模式适用于所有的window,document,node,form,mouse和keyboard事件。

on方法不仅可实现API注册事件,而且规范化了事件处理程序是如何工作的:

(1)事件处理器按照注册的顺序来调用

(2)当事件处理器被调用时,第一个参数始终为一个事件对象。

(3)事件对象会有一个target属性,一个stopPropagation方法,和一个preventDefault方法

如同DOM API一样,Dojo提供删除事件处理器的方法handle.remove。on方法的返回值是一个拥有remove方法的简单对象,调用方法删除事件监听。例如你想要一个只执行一次的方法你可以按照下面做:

var handle = on(myButton,function(evt){
    // Remove this event using the handle
    handle.remove();
                                                                                                                                                
    // Do other stuff here that you only want to happen one time
    alert("This alert will only happen one time.");
});

dojo/on包含了一个便利的方法处理这些一次性的事件on.once,他接收和on一样的参数。

on方法第一参数是事件处理程序的上下文,一个例外是:当on 使用委派事件。你可以使用lang.hitch(在dojo/_base/lang模块中)指定运行处理器的上下文。

require(["dojo/on","dojo/_base/lang",lang) {
                                                                                                                             
        var myScopedButton1 = dom.byId("myScopedButton1"),myScopedButton2 = dom.byId("myScopedButton2"),myObject = {
                id: "myObject",onClick: function(evt){
                    alert("The scope of this handler is " + this.id);
                }
            };
                                                                                                                             
        // This will alert "myScopedButton1"
        on(myScopedButton1,myObject.onClick);
        // This will alert "myObject" rather than "myScopedButton2"
        on(myScopedButton2,lang.hitch(myObject,"onClick"));
                                                                                                                             
});


2、NodeList事件

dojo.NodeList提供了on方法用于向多个节点注册事件,NodeList.on方法与dojo/on方法类似,没有dojo/on方法中的第一个参数,因为在NodeList中你正在关联的节点是一个对象。dojo/query包含了NodeList.on方法,所以你不需要引用dojo/on

<!DOCTYPE html>
<html>
<head lang="en">
    <Meta charset="UTF-8">
    <title></title>
    <style>
        #myButton {
            margin-bottom: 1em;
        }
        #myDiv {
            border: 1px solid black;
            background-color: white;
            width: 100px;
            height: 100px;
        }
    </style>
    <script src="dojo/dojo.js" data-dojo-config="async: true"></script>
    <script>
        require(["dojo/query",function(query,lang) {
            var myObject = {
                id: "myObject",onClick: function(evt){
                    alert("The scope of this handler is " + this.id);
                }
            };
            query(".clickMe").on("click",myObject.onClick);
            query(".clickMeAlso").on("click","onClick"));
        });
    </script>
</head>
<body>
<button id="button1" class="clickMe">clickMe</button>
<button id="button2" class="clickMeAlso">clickMeAlso</button>
<button id="button3" class="clickMe">clickMe</button>
<button id="button4" class="clickMeAlso">clickMeAlso</button>
</body>
</html>

备注:NodeList.connect方法返回一个dojo.NodeList对象以用于链式调用,而NodeList.on返回一个存放on事件处理器的一个数组,该数组包含一个remove方法


3、事件委托

事件委托格式:on(parent element,"selector:event name",handler)

<!DOCTYPE html>
<html>
<head lang="en">
    <Meta charset="UTF-8">
    <title></title>
    <style>
        #myButton {
            margin-bottom: 1em;
        }
        #myDiv {
            border: 1px solid black;
            background-color: white;
            width: 100px;
            height: 100px;
        }
    </style>
    <script src="dojo/dojo.js" data-dojo-config="async: true"></script>
    <script>
        require(["dojo/on","dojo/query",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>
</head>
<body>
<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>
</body>
</html>

注意:虽然我们不直接的使用dojo/query,但此模块仍然是需要的。这是因为dojo/on需要dojo/query暴露选择器引擎,以便能够匹配事件委托所使用的选择器。


4、Publish/Subscribe(发布/订阅

在此之前,以上的所有例子都使用一个已存在的对象作为事件的发生器(你注册的等待事件的发生)。如果你没有一个节点的引用,或者并不知道对象是否已经创建。这就是dojo 的发布/订阅框架引入的原因。通过 dojo/topic模块,Pub/sub允许你为一个主题注册一个处理器,(主题是一个事件的别名,此事件是多源的,以字符串形式描述)当配发布的时候主题将被调用。我们设想一下,在我们开发的应用中,我们需要一些按钮,来弹出动作的用户,我们想要一次性的将弹出写完,我们也不想创建一个包装对象,同过按钮来注册小程序,Pub/sub能够应用在此场景中。

<!DOCTYPE html>
<html>
<head lang="en">
    <Meta charset="UTF-8">
    <title></title>
    <style>
        #myButton {
            margin-bottom: 1em;
        }
        #myDiv {
            border: 1px solid black;
            background-color: white;
            width: 100px;
            height: 100px;
        }
    </style>
    <script src="dojo/dojo.js" data-dojo-config="async: true"></script>
    <script>
        require(["dojo/on","dojo/topic","dojo/dom-construct",topic,domConstruct,dom) {
                    var alertButton = dom.byId("alertButton"),createAlert = dom.byId("createAlert");
                    on(alertButton,function() {
                        // When this button is clicked,// publish to the "alertUser" topic
                        topic.publish("alertUser","I am alerting you.");
                    });
                    on(createAlert,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,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>
</head>
<body>
<button id="alertButton">Alert the user</button>
<button id="createAlert">Create another alert button</button>
</body>
</html>

订阅/发布模式是靠主题把事件和事件处理函数联系起来的。如果你想停止接收主题,topic.subscribe方法返回一个对象,该对象具有remove方法,可以用来删除相应的处理程序。

dojo.subscribe = function(/*String*/ topic,/*Object|null*/ context,/*String|Function*/ method)

subscribe 函数用来订阅某一主题;参数 topic 表示主题名字,是一个字符串; context 是接收到主题调用的事件处理函数所在的对象,function 是事件处理函数名。

dojo.publish = function(/*String*/ topic,/*Array*/ args)

发布某一主题;参数 topic 是主题的名字,args 表示要传递给主题处理函数的参数,它是一个数组,可以通过它传递多个参数给事件处理函数


参考文献:1.http://dojotoolkit.org/documentation/tutorials/1.9/events/

2.http://www.ibm.com/developerworks/cn/web/wa-lo-dojointro3/

猜你在找的Dojo相关文章