Dojo1.11官方教程文档翻译(3.3)Dojo 事件

2024-03-11 04:48

本文主要是介绍Dojo1.11官方教程文档翻译(3.3)Dojo 事件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

3.3 Dojo事件

原文地址:https://dojotoolkit.org/documentation/tutorials/1.10/events/index.html
GitBook地址:https://www.gitbook.com/book/limeng1900/dojo1-11-tutorials-translation-in-chinese/details
转载请注明出处:http://blog.csdn.net/taijiedi13/ – 碎梦道


本教程中,我们将探索dojo/on以及Dojo如何更容易地连接DOM事件。我们也将探索Dojo的publish/subscribe框架:dojo/topic

入门

你的许多JavaScript代码都用来为事件做准备:包括生成和相应新事件。就是说构建响应式、交互式web应用的关键就是创建高效的事件连接。事件连接可以让你的应用响应用户交互和等待动作的发生。Dojo中DOM事件的主力是dojo/on,下面一起来看如何使用这个模块。

DOM事件

你会问自己“DOM不是已经提供了一个机制来注册事件处理程序么?”答案是yes,但并不是所有的浏览器都遵循 W3C DOM 规范。在各种主流浏览器里主要有三种方式来注册事件处理器:addEventListenerattachEvent和 DOM 0。除此之外,还有两个不同的事件对象实现和至少一种 fires registered listeners in random order.aspx) and leaks memory.aspx)的浏览器引擎。Dojo改善了你使用DOM事件的方式,用一个名叫dojo/on的单一、直白的事件API将各种原生API标准化并阻止内存泄漏。
假设我们有以下标记:

<button id="myButton">Click me!</button>
<div id="myDiv">Hover over me!</div>

再想象一下,你想要在点击按钮的时候让div变成蓝色,鼠标经过时变为红色,完成悬停后变回白色。dojo/on很容易实现:

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", "");});
});

注意也require了dojo/mouse。不是所有的浏览器原生支持mouseentermouseleave事件,所以用dojo/mouse来添加支持。你可以自己编写像dojo/mouse一样的模块来支持其他自定义事件类型。
这个例子阐述了常见模式: on(element,event name,handler)。或者换个说话就是某个元素上的某个事件连接某个处理器。该模式适用于全部的window、document、node、 form、mouse和keyboard事件。
注意和旧的dojo.connectAPI不一样,使用dojo/on模块时,事件名称的“on”前缀必须省略。
on方法不仅仅规范了事件注册的API,还规范了事件处理器的工作方式:

  • 事件处理器总是按注册的顺序调用。
  • 它们调用时都将一个事件对象作为第一个参数,
  • 事件对象总是规范的包含常见W3C事件对象属性、类似target属性、一个stopPropagation方法和一个preventDefault方法。
    就像DOM API,Dojo提供一个方法来移除一个事件处理器:_handle_.removeon的返回值是一个带有remove方法的简单对象,调用该方法是将移除事件监听。例如,如果你想要一个一次性的事件,你就可以这么做:
var handle = on(myButton, "click", function(evt){// Remove this event using the handlehandle.remove();// Do other stuff here that you only want to happen one timealert("This alert will only happen one time.");
});

顺便提下,dojo/on还有一个简便的方法:on.once。它接收和on一样的参数,但是会在它触发一次之后移除处理程序。
最后要说明的是:默认情况下,on将会在将节点传递为第一参数的上下文中运行事件处理器。例外是当它用来事件委托时,稍后就会讨论。

无论如何,你可以使用lang.hitch(来自dojo/_base/lang模块)来指定运行处理器的上下文。当使用对象方法时,hitch非常有用:

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"));});

View Demo

不像它的前任dojo.connecton不接受处理器作用域和方法参数。你需要为第三个参数使用lang.hitch,如果你希望保持执行语境。

NodeList事件

前面的教程提到过,NodeList提供一种多节点注册事件的方式:on方法。这个方法遵循dojo/on相同的模式,但没有第一个参数(由于NodeList的节点是你将要连接的对象)。

on方法包含在dojo/query里,所以你用NodeList.on时不需要专门requiredojo/on
让我们看一个更高级的例子:

<button id="button1" class="clickMe">Click me</button>
<button id="button2" class="clickMeAlso">Click me also</button>
<button id="button3" class="clickMe">Click me too</button>
<button id="button4" class="clickMeAlso">Please click me</button>
<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>

记住不同于NodeList.connectNodeList.on方法并不返回NodeList,反之,它返回一个稍后可removeon处理器的数组。 这个数组也包含一个便利的最高阶remove方法,可以一次移除全部的监听器。

View Demo

事件委托

上面讨论过,NodeList的on方法可以很容易的把相同事件的同一处理器连接到多个DOM节点上。dojo/on也可以通过更高效的事件委托来实现这个。
事件委托背后的理念不是对每一个独立兴趣节点绑定一个事件监听,而是给一个节点在更高层面上单独附加一个监听器,它会检查捕获的事件的目标,看这些目标是否是从真实的兴趣节点冒泡来的,如果是则执行处理器逻辑。
以前这个可以(现在仍可以)通过dojox/NodeList/delegate来扩展NodeList。在1.10中就可以用dojo/on模块,语法是on(parent enement, "selector:event name ", handler)
为了更好的说明,来看另一个基于和之前相同premise的例子:

<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>

请注意,我们也需要require dojo/query模块,虽然并不直接使用它。因为dojo/on需要dojo/query提供的选择器引擎来实现事件委托的选择器匹配。为了减少封装和避免不经常使用的特性困扰开发者,它没有被dojo/on自动引入。

View Demo

在运行上面的例子时,注意this仍然引用实际的兴趣节点,不是parentDiv节点。这是使用on进行事件委托的重要区别:this不再引用第一个参数传入的节点,而是选择器匹配的节点。这会非常有用。

对象方法

dojo/on的前任——dojo.connect曾经也可实现 function-to-function的事件连接。这个功能已经划分到了名叫dojo/aspect的资源。你很快会在后面的dojo/aspect的教程中看到。

Publish/Subscribe

目前为止的所有例子都是用已存在的对象作为一个事件生成器,当发生一些事情时注册的这个对象可以了解到。不过,如果你没有一个节点的处理器或者不知道是否创建了一个对象时应该怎么办?这里引入Dojo的发布和订阅(pub/sub)框架,它在1.10版本的dojo/topic模块里。你可以用pub/sub为“topic”(这是一个有趣的事件名称,可以有多种资源,表示为一个字符串)注册一个处理器(订阅)。
想象一下在我们正在开发的一个应用中,我们想要确保按钮会在用户的动作下弹出信息,不打算编写例行程序来弹出不止一次,但是也不想要一个在按钮上注册这个小程序的包装对象。这里可以使用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" topictopic.publish("alertUser", "I am alerting you.");});on(createAlert, "click", function(evt){// Create another buttonvar anotherButton = domConstruct.create("button", {innerHTML: "Another alert button"}, createAlert, "after");// When the other button is clicked,// publish to the "alertUser" topicon(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>

View Demo

这种模式的一个优势在于我们不需要创建任何DOM对象就可以在单元测试中测试我们的弹出程序:这个程序和事件生成器不挂钩。
如果你想要停止获取一个topic的通知,topic.subscribe返回一个带有remove方法的对象,这个方法可以用来移除单个处理器(就像on)。

注意和dojo.publish不同,topic.publish不希望通过数组来传递发布参数。例如,topic.publish("someTopic", "foo", "bar")等同于dojo.publish("someTopic", ["foo", "bar"])

小结

Dojo事件虽然用起来很简单,但是非常强大。on方法可以将不同浏览器间DOM事件的差异规范化。Dojo的pub/sub框架、dojo/topic向开发者提供了将事件处理器从事件生成器分离出来的方法。花点时间来熟悉这些工具吧,它们在创建web应用时非常有用。

这篇关于Dojo1.11官方教程文档翻译(3.3)Dojo 事件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/796687

相关文章

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

Python自动化处理PDF文档的操作完整指南

《Python自动化处理PDF文档的操作完整指南》在办公自动化中,PDF文档处理是一项常见需求,本文将介绍如何使用Python实现PDF文档的自动化处理,感兴趣的小伙伴可以跟随小编一起学习一下... 目录使用pymupdf读写PDF文件基本概念安装pymupdf提取文本内容提取图像添加水印使用pdfplum

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

Java Scanner类解析与实战教程

《JavaScanner类解析与实战教程》JavaScanner类(java.util包)是文本输入解析工具,支持基本类型和字符串读取,基于Readable接口与正则分隔符实现,适用于控制台、文件输... 目录一、核心设计与工作原理1.底层依赖2.解析机制A.核心逻辑基于分隔符(delimiter)和模式匹

spring AMQP代码生成rabbitmq的exchange and queue教程

《springAMQP代码生成rabbitmq的exchangeandqueue教程》使用SpringAMQP代码直接创建RabbitMQexchange和queue,并确保绑定关系自动成立,简... 目录spring AMQP代码生成rabbitmq的exchange and 编程queue执行结果总结s

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图