让我们开始吧
开始学习Dojo的最简洁方法之一就是通过内容分发网络(CDN)来获取它,这将会让我们起步很快,使用CDN就意味着你的浏览器要接入互联网
这种方法将使我们快速地进入使用Dojo。对于一些产品应用或者大规模开发,我们接下来将介绍其他的一些能发挥更好性能的开发方法。
你需要将你所有的例子放在你的本地网络服务器上,这样就可以在特定的工作环境下浏览你的文件,并能在很多细微之处保证你的工作安全无误。运行这些例子你不需要在你的服务器上增加除了文件服务的其他功能就能出色地完成测试。
本篇教程是为Dojo新手所准备的,如果你已经掌握了1.7版本以前的知识并且想了解新版本更新了什么,你可能需要开始学习 "Modern Dojo" 这篇文章。
为了“引导”Dojo,你得加载 dojo/dojo.js 这个文件并提供它一些配置信息:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Tutorial: Hello Dojo!</title>
</head>
<body><h1 id="greeting">Hello</h1><!-- load Dojo --><script src="//ajax.googleapis.com/ajax/libs/dojo/1.8.1/dojo/dojo.js"data-dojo-config="async: true"></script>
</body>
</html>
以上代码使得Dojo loader(Dojo加载器)能够被网页所运行,Dojo loader 的功能就是让你加载Dojo的modules(模块)。
你也许会疑惑“嘿,代码中的"src"属性少了"http:" ,好吧,这并不为大众所知,但是如果你省略了"URL"的协议,那么浏览器就会猜测页面加载的协议。这就意味着你的页面不管是从"http"或者"https"协议加载的都会正常地运行。如果你不这样做,就会导致你的浏览器在某些"https"环境下弹出警告,这显然不是好的用户体验。如果你在自己的设备上运行这些代码,确保你是在本地网络服务器上运行的,那是因为在"file:"协议下,这些代码不会工作。出于很多原因,你应该始终在网络服务器或者本机的网络服务器上运行Dojo。”
另一个你可能注意到的是"data-dojo-config"属性。这个特殊的HTML5属性是在被加载时用来配置Dojo的,它包含了一系列属性,并且它的样式和功能都像一个" object literal (JavaScript对象字面) " ,只不过没有打开和关闭的大括号标记而已。在这种情况下,我们将介绍在异步模式下运行的Dojo。这是在Dojo1.7引入的新的模式,如果你正在全新的开发,你应该默认使用这种模式。再强调一次,如果你是从老版本(1.7以前)迁移过来的你得先学习 "Modern Dojo" 文章来更好地了解他们的变化。
你可以在 Configuring Dojo with dojoConfig 文章里了解到更多的Dojo的配置内容
我们也将"<script>"标签块放在HTML文档的"body"中,我们可以将它放在"header"中并且效果是一样的,但当在你的应用程序的"header"里的"<script>"块里加载大量代码时,会导致代码在加载时,网页处于渲染状态。这会让用户感觉你的应用程序运行缓慢从而降低用户体验,所以我们一般在文档的"body"结尾处加载Dojo代码。
从Dojo1.7开始,Dojo采用 Asynchronous Module Definition (AMD)/(异步模块定义) 作为标准的JavaScript模块。这就允许Dojo不仅能提供异步模块加载的功能增强,而且使Dojo比以往更加模块化,无需全局变量。Dojo AMD标准同样允许Dojo加载使用其他AMD加载器加载的非Dojo模块。
同早期版本的Dojo对比,早期Dojo会自动加载全部的"base"函数,当运行异步模块的Dojo时(async:true),Dojo只加载那些被引用的模块,而不加载无用的模块。这就使得应用程序有更好的表现。另外,Dojo的模块被重写使,不需要依赖更多的Dojo,只是按需要在自己的模块引用其他模块,除了"loader(加载器)"没有其他的模块能够自动被加载。这就是经常提到的"baseless"Dojo。
Dojo1.8所有的文章系列都是用的"baseless"Dojo,旨在加载需要加载的模块,使网络应用程序更轻更好。
CDN的使用
CDN是很容易获取的。我们在文章的例子里都是使用的CDN,因为这意味着你可以直接复制代码并不需要做任何改动就可以让他们为你服务。但它们也有以下缺点:
- 由于性能的原因,它们都是压缩的版本,这就意味着每个模块都是最小最优化的,在网络上传输地更有效率。这就带来一个问题,很难去调试
- 它们需要用户连接到公共网络才能使用你的应用程序,在很多情况下不实用。
- 它还要加载你自己的模块
- 如果你想将你的应用程序投入生产,你将得大大益于一个针对特定应用程序和目标浏览器的压缩版Dojo,这样你就不能获得同样大小又适用于所有CDN的压缩版Dojo
还有一些其他的文章在不同方面介绍了CDN带来的挑战。查看 Creating Builds , Using Custom Modules with a CDN ,以及 Configuring Dojo with dojoConfig 。
如果你想成为一个卓越的开发者,你应该下载Dojo的源代码并且安装在你本地服务器上。为了使你的demo程序能够在你本地设备上运行,你还得将包含demo代码的文件夹与Dojo源代码文件夹放在同一目录下。如下图:
然后修改加载Dojo的路径:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Tutorial: Hello Dojo!</title>
</head>
<body><h1 id="greeting">Hello</h1><!-- load Dojo --><script src="../dojo/dojo.js"data-dojo-config="async: true"></script>
</body>
</html>
定义和引用模块
Dojo中的模块被分成不同的代码块以方便单独调用。他们通过字符串被标识,这些字符串跟文件路径很像。举个例子,my/module/id 就是Dojo1.7以及更新版本的module identifier (MID)模块标识符。实际上,这些标识符是用来映射JavaScript文件的,像"my/module/id"加载模块的请求就会触发loader(加载器)加载定义在路径"my/module/id.js"中的模块。
还有一些更加复杂的方式来映射模块和文件,但使用简单的路径结构方式是所有方式中最典型的。
为了使定义和请求的模块能够正确地在你的应用程序中运行, two global functions are provided by the loader :.require()是用来加载一个或更多模块的,define()用来定义一个模块。这两个函数通常带有两个参数:一系列需要加载的MID,和一个回调函数,这个回调函数在所有MID加载完成后就会执行。
通过简单的例子就很容易解释了,首先让我们定义一个模块:
// 文件在 demo/myModule.js里 (这就定义了一个"demo/myModule"模块):define([//这个模块需要引用 dojo/dom 模块,这里就需要加入它"dojo/dom"
], function(dom){//当所有依赖的模块都加载完毕后,这个方法就会执行从而定义dome/myModule模块//dojo/dom作为第一个参数加入这个函数中,其后的依赖项会紧接这加入作为后续参数var oldText = {};//这里返回的对象就是这个模块所要定义的值return {setText: function(id, text){var node = dom.byId(id);oldText[id] = node.innerHTML;node.innerHTML = text;},restoreText: function(id){var node = dom.byId(id);node.innerHTML = oldText[id];delete oldText[id];}};
});
这个demo模块有一个依赖模块(dojo/dom),模块的返回值是一个对象,对象拥有setText和restoreText两个方法。
因为我们正在通过CDN使用Dojo,但我们想从本地加载我们自定义的模块,我们就得修改配置来改变加载模块的方法。要不然Dojo加载器就会认为我们自定义的模块在CDN上。关于这些深入的介绍在 Using Custom Modules with a CDN 这篇文章里,现在我们只需要知道它是如下工作的:
<script>//除了data-dojo-config标签,我们在加载dojo.js之前创建一个dojoConfig对象//他们功能上是完全一致的,它只不过比前者更容易读取大的配置文件var dojoConfig = {async: true,//这里的代码注册了demo包的正确路径,这样我们就可以在CDN上加载Dojo的同时加载本地自定义模块packages: [{name: "demo",location: location.pathname.replace(/\/[^/]*$/, '')}]};
</script>
如果你在你自己的服务器上安装了源代码,就不需要做这一步了。
既然我们已经创建了自己的模块并且更改了Dojo的配置,我们就可以加载并利用它做些什么了:
//引用我们创建的模块
require(["demo/myModule"], function(myModule){//利用我们的模块改变问候的文本myModule.setText("greeting", "Hello Dojo!");//几秒钟后,恢复文本到原来的状态setTimeout(function(){myModule.restoreText("greeting");}, 3000);
});
使用我们自定义的模块,这些代码轻松地将<h1 id="greeting">元素改变为"Hello Dojo!",过3秒后再将它还原为原来的内容。注意我们不需在require里引用所有的子级依赖,加载器将自动地加载需要的所有子级依赖,直到所有引用加载完毕。
进一步学习定义和引用Dojo的模块,参考文章: Defining Modules
等待DOM
要完成网络应用程序前最常见的事情之一就是在执行代码前确保浏览器的DOM是可用的。在Dojo1.7以及更新版本的异步模型中,DOM检查被一个叫"plugin"的特殊AMD模型所完成。Plugin可以像其他模块一样被引用,但他们的特定功能只有在模块标识符的结尾加上感叹号后才会被激活。在DOM ready事件完成后,Dojo提供了dojo/domReady插件,将这个插件包含在任何含有require和define调用的参数里,直到所有的DOM准备无误回调函数才会运行:
require(["dojo/dom", "dojo/domReady!"], function(dom){var greeting = dom.byId("greeting");greeting.innerHTML += " from Dojo!";
});
以上的例子在"gressting"节点上添加文本,这种行为只会在DOM加载完毕后准确地执行一次。再一次强调,注意模块标示符结尾加上"!",如果没有感叹号,dojo/domReady模块就跟其他模块一样。
更多关于DOM操作功能请参考 Dojo DOM Functions
添加动画效果
现在我们可以在我们的例子中增加一些动画效果。可以加载到页面里增叫动画效果的模块是dojo/fx,让我们利用dojo/fx中的slideTo方法为greeting节点增叫一个滑动效果:
require(["dojo/dom", "dojo/fx", "dojo/domReady!"], function(dom, fx){var greeting = dom.byId("greeting");greeting.innerHTML += " from Dojo!";//调用动画方法fx.slideTo({top: 100,left: 200,node: greeting}).play();
});
你可以发现,我们又添加了dojo/fx模块,然后我们使用这个模块给greeting节点增加了动画。当地一次使用AMD的时候,你也许会错误地认为MID数组(["dojo/dom","dojo/fx","dojo/domReady!"])和回调函数的参数(function(dom,fx))没任何关系。然而,他们确实有关系。当回调函数获取参数时,模块会以同样的顺序作为数组传入进去。因为dojo/domReady!并没有有意义的返回值,所以我们我们不需要为它添加用于返回的参数。 不要错误认为只是你不需要使用那个值,JavaScript或者Dojo就会自动计算它。要知道,任何返回不需要使用的值模块都得放在数组的最后。举个例子,下面的做法就是错误的:
require(["dojo/dom", "dojo/domReady!", "dojo/fx"], function(dom, fx){//并不是你想象的那样,fx会映射dojo/domReady!,而不是dojo/fx
});
更多的特效和动画信息可以参考 Dojo Effects 和 Animations
如何进一步学习Dojo?
学习Dojo ToolKit和添加一个标签以及引用模块一样简单,但功能及其广泛和强大的Dojo意味着我们只能勉强掌握Dojo表面的皮毛。依据你的需求,我们提供了一系列不同方向的文章:
- 如果你以前使用过Dojo并且想进一步了解带有"AMD"和"baseless"的Dojo世界,以及Dojo其他改进的地方,你需要参考 Modern Dojo 文章。
- 如果你的兴趣是在你既有的静态网页或服务驱动网站页面上添加特效和动画效果,你需要阅读 Using dojo/query , Events with Dojo , effects 和 animations 这些文章。
- 如果你想添加Ajax功能到你的网站, Ajax with Dojo 将会是不错的选择。
- 如果你打算为你的网站或应用程序整合一套丰富的部件库,你可以看依稀 Creating Template-based Widgets 并通过 tutorial series on Dijit widgets 强化知识。
- 如果你想了解更多关于构建复杂的网络应用程序和Dojo强大的实用功能,向 Core Concepts 看齐吧。
- 如果你的目标是移动应用程序,快跟着 Getting Started with dojox/mobile 开始吧。
无论你想要什么结果,Dojo提供了业界领先的开放源代码工具,可以帮助您完成您的项目在较短的时间以惊人的结果。我们期待着看到你了!
本系列文章翻译至Dojo官网,旨在学习Dojo并提高英语阅读能力,有翻译错误的地方请多指正!谢谢