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

简介:

1、DOM事件

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

   页面on.html代码如下:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!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, function(evt){
                         domStyle.set(myDiv, "backgroundColor", "red");
                     });
                     on(myDiv, mouse.leave, function(evt){
                         domStyle.set(myDiv, "backgroundColor", "");
                     });
                 });
     </ 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方法的简单对象,调用此方法将删除事件监听。例如你想要一个只执行一次的方法你可以按照下面做:

1
2
3
4
5
6
7
var  handle = on(myButton,  "click" 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模块中)指定运行处理器的上下文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
require([ "dojo/on" "dojo/dom" "dojo/_base/lang" "dojo/domReady!" ],
     function (on, dom, 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,  "click" , myObject.onClick);
         // This will alert "myObject" rather than "myScopedButton2"
         on(myScopedButton2,  "click" , lang.hitch(myObject,  "onClick" ));
                                                                                                                              
});


2、NodeList事件

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!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" "dojo/_base/lang" "dojo/domReady!" ],  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" , lang.hitch(myObject,  "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)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!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/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 >
</ 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能够应用在此场景中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!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", "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 >
</ 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/



     本文转自stock0991 51CTO博客,原文链接:http://blog.51cto.com/qing0991/1399156,如需转载请自行联系原作者







相关文章
|
存储 JavaScript 前端开发
Dojo学习和常用知识
@[TOC](目录) Dojo 是一个流行的 JavaScript 库,用于开发 Web 应用程序。它提供了许多功能,如 DOM 操作、事件处理、动画效果、数据存储和许多其他实用功能。在今天的 Web 开发中,Dojo 仍然被广泛使用,尤其是在企业级应用程序开发中。 下面是一个详细的 Dojo 详解,包括代码实例。 # 一、Dojo 的基本概念 1. Dojo 模块 Dojo 模块是 Dojo 的基本构建块。每个模块都是一个 JavaScript 文件,它包含了实现特定功能的代码。模块可以分为两类:核心模块和扩展模块。 核心模块是 Dojo 库的基础部分,提供了许多基本的功能,如 DOM 操作
179 0
|
JavaScript 前端开发 移动开发
|
JavaScript 前端开发 CDN
|
JavaScript 前端开发 数据管理
|
JavaScript 前端开发 .NET

热门文章

最新文章