http://dojotoolkit.org/documentation/tutorials/1.10/hello_dojo/index.html
欢迎学习DOJO!在本教程中,你将学些到如何加载DOJO,并能够了解DOJO的一些核心功能。你也会了解到DOJO的AMD模式,一种基于模块化架构。该架构可以让你通过扩展模块的方式扩展你的网站或应用的功能,发现错误的时候,如何找到解决方案。
开始
使用DOJO很简单,就像使用其他的javascript文件一样,我们只需要把dojo.js文件包含到问的页面里面就可以了。DOJO在CDN上很流行,这意味着我们可以直接在CDN上直接发布的DOJO库。下面我们就创建一个html文件,命名为hellodojo.html
,在该文件中输入一下内容,保存后,使用浏览器打开。
1 <!DOCTYPE html>
2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Tutorial: Hello Dojo!</title> 6 </head> 7 <body> 8 <h1 id="greeting">Hello</h1> 9 <!-- load Dojo --> 10 <script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" 11 data-dojo-config="async: true"></script> 12 </body> 13 </html>
一般情况下,一旦你加载了javascript库文件之后,你就可以使用该文件定义的所有功能。在过去的dojo版本中是这样的,但从1.7版本开始,dojo采用得了异步模块定义模式(AMD),该模式可以让开发人员采用模块化的方式开发Web应用。之所以选择AMD模式,是因为该模式基于存jsvascript代码环境工作,并可以让源代码在Web浏览器下运行。AMD可通过优化资源生成和加载方式,提高Web应用的资源加载效率,以提高系统性能。
当Dojo.js被加载之后,我们可以使用哪些功能呢?我们可以使用dojo的AMD模式的模块装载器,该装载器定义了require
和define
两个全局函数。后面我们有专门介绍AMD的文章。作为初始DOJO,我们只要知道require函数是加载一个模块以使用它们,而define函数是用来定义我们自己的模块。 一般情况下,每个模块都对应着一个javascript物理文件。
dojo/dom和dojo/dom-construct就是dojo为操作html DOM定义的一些基础模块,下面让我们看下如何加载这些模块,并使用它们。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Tutorial: Hello Dojo!</title> 6 </head> 7 <body> 8 <h1 id="greeting">Hello</h1> 9 <!-- load Dojo --> 10 <script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" 11 data-dojo-config="async: true"></script> 12 13 <script> 14 require([ 15 'dojo/dom', 16 'dojo/dom-construct' 17 ], function (dom, domConstruct) { 18 var greetingNode = dom.byId('greeting'); 19 domConstruct.place('<em> Dojo!</em>', greetingNode); 20 }); 21 </script> 22 </body> 23 </html>
require
函数的第一个参数(14-17行)是模块标识列表,用来标识你想加载哪些模块。一般情况下,这些模块的标识都映射了定义模块的Javascript文件名。如果你下载了dojo的源码发布包,打开dojo文件夹,你会在该文件夹下发现dom.js
和dom-construct.js
文件,这两个文件就分别定义了'dojo/dom'和'dojo/dom-construct'两个模块。
AMD加载模块的操作是异步执行的,我们也知道,一般在javascript中,执行异步操作后,都会有回调函数。require
函数的第二个参数(17行)就是定义的回调函数,在这个函数中,你就可以使用加载的模块提供的功能编写你自己的javascript代码。AMD加载器会把每个模块当成参数传递给回调函数,顺序和模型标识数组中的顺序是一致的。你可以随意的命名回调函数中的参数名字,但为了代码的可读性,一般我们会以模块的标识名称或者相似的名字为参数命名。例如上面的代码中,把"dojo/dom"模块对应的参数命名为dom,把dojo/dom-construct模块对应的回调函数参数命名为domconstruct。当然你也可以把这两个模块对应的参数分别命名为A和B,我们的代码同样是可以正常工作的,但我们不建议你这样命名。
在代码的第18和19行,你可以看到我们利用模块dom和dom-construct模块,通过id获取了dom节点,并修改了节点的内容。
AMD加载器会自动的加载我们请求加载模块所依赖的其他模块,所以你只要把你直接需要调用的模块添加到依赖列表中就可以了,即require
函数的第一个参数中。
定义AMD模块
在上面你已经通过实例了解了如何加载和使用模块。下面我们定义个自己的模块,并加载使用它。在此之前,你需要一个自己的HTTP服务器,从HTTP服务器上加载HTML文件。本地文件也是可以的,但有时候本底文件由于安全性的一些问题,会造成运行结果有些细微的差别。对于这些例子,你不需要在你的Web服务器上做更多的配置,只要能够正常发布服务文件就可以了。在HelloDojo.html页面的同级目录下创建demo目录,在demo下创建myModule.js
文件。
demo/
myModule.js
hellodojo.html
在该文件中输入一下代码:
1 define([ 2 // The dojo/dom module is required by this module, so it goes 3 // in this list of dependencies. 4 'dojo/dom' 5 ], function(dom){ 6 // Once all modules in the dependency list have loaded, this 7 // function is called to define the demo/myModule module. 8 // 9 // The dojo/dom module is passed as the first argument to this 10 // function; additional modules in the dependency list would be 11 // passed in as subsequent arguments. 12 13 var oldText = {}; 14 15 // This returned object becomes the defined value of this module 16 return { 17 setText: function (id, text) { 18 var node = dom.byId(id); 19 oldText[id] = node.innerHTML; 20 node.innerHTML = text; 21 }, 22 23 restoreText: function (id) { 24 var node = dom.byId(id); 25 node.innerHTML = oldText[id]; 26 delete oldText[id]; 27 } 28 }; 29 });
AMD的define函数接受的参数和reqiure函数接受的参数类似,都是模块标识数组以及一个回调函数。AMD加载器保存了回调函数返回的值,回调函数返回的值就是该自定义模块提供的功能。当其他的代码通过require函数或define函数加载该模块候,都可以调用该模块定义的这些功能,即回调函数返回的一些函数等。
CDN的使用
通过Dojo加载本地自定义的一些模块需要一些额外的配置。更详细的内容会再后面的章节中介绍。
下面把Hellodojo.html中的代码更新为以下内容。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Tutorial: Hello Dojo!</title> 6 </head> 7 <body> 8 <h1 id="greeting">Hello</h1> 9 <!-- configure Dojo --> 10 <script> 11 // Instead of using data-dojo-config, we're creating a dojoConfig 12 // object *before* we load dojo.js; they're functionally identical, 13 // it's just easier to read this approach with a larger configuration. 14 var dojoConfig = { 15 async: true, 16 // This code registers the correct location of the "demo" 17 // package so we can load Dojo from the CDN whilst still 18 // being able to load local modules 19 packages: [{ 20 name: "demo", 21 location: location.pathname.replace(/\/[^/]*$/, '') + '/demo' 22 }] 23 }; 24 </script> 25 <!-- load Dojo --> 26 <script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script> 27 28 <script> 29 require([ 30 'demo/myModule' 31 ], function (myModule) { 32 myModule.setText('greeting', 'Hello Dojo!'); 33 34 setTimeout(function () { 35 myModule.restoreText('greeting'); 36 }, 3000); 37 }); 38 </script> 39 </body> 40 </html>
上述代码中,我们对dojo进行了配置,并加载demo/myModule定义了主体代码,这段代码可完成对页面的一些操作。就如你看到的,定义和加载模块是比较简单的。We've also changed the URL to dojo.js to omit the protocol (line 26) - this creates a link that uses whatever protocol the page is using (http or https), preventing mixed content which raises security warnings in some browsers.
使用AMD模式可以帮助你组织模块化的javascript源代码,且可在浏览器中立即执行,并能够很好的进行调试。AMD模块使用局部命名方式为变量命名,这样可以避免使用全局命名方式导致的代码混乱,并可以提高名称解析速度。AMD是一种标准协议,包含了多种实现方式。所以你不必拘泥于一种实现方式,任何基于AMD的加载器都可以加载使用基于ADM定义的模块。
等待DOM加载完成
进行Web应用开发时,常要处理的问题之一就是在执行代码之前,要确保页面的DOM节点都已经加载并可以正确获取。在dojo中,使用一种称为"插件"的特殊AMD模块实现。插件和其他ADM模块一样可以被调用,but their special functionality is only activated by adding an exclamation point (bang) to the end of the module identifier。在DOM节点加载准备完毕事件上,dojo提供了dojo/domReady
插件。主要define或reqiure函数再模块依赖中使用了该插件,那么其调用函数只会在DOM加载完毕后才会被调用。
1 require([ 2 'dojo/dom', 3 'dojo/domReady!' 4 ], function (dom) { 5 var greeting = dom.byId('greeting'); 6 greeting.innerHTML += ' from Dojo!'; 7 });
上面的例子是在greeting节点上加载了一些文本,而完成这些工作必须要等DOM节点加载完毕才能执行。请注意,代码在加载dojo/domReady模块时,后面加了!符号。如果没有该符号,dojo会把该模块当成普通的AMD模块处理。
在一些情况下,我们调用例如dojo/domReady这样的模块,不是为了调用其定义的功能,而是另有他用。但AMD加载器对此一无所知,它依旧把每个模块作为参数传递给回调函数。所以有一些你不需要调用的模块标识,可以放在模块标识数组的最后面,在回调函数中,就可以忽略这些模块。
后面的文章还会对Dojo操作DOM有具体的描述。
添加视觉效果
现在我们可以通过添加一些动画效果,让我们的例子看起来更加生动活跃一些。我们可以加载dojo/fx
模块来给我们的页面添加效果。下面我们通过dojo/fx
模块的slideTo
函数给greeting节点添加渐变动画。
1 require([ 2 'dojo/dom', 3 'dojo/fx', 4 'dojo/domReady!' 5 ], function (dom, fx) { 6 // The piece we had before... 7 var greeting = dom.byId('greeting'); 8 greeting.innerHTML += ' from Dojo!'; 9 10 // ...but now, with an animation! 11 fx.slideTo({ 12 node: greeting, 13 top: 100, 14 left: 200 15 }).play(); 16 });
如上代码所示,我们又增加了一个队dojo/fx模块的依赖,并使用该模块在greeting节点上播放动画。
使用dojo源码
CDNs是最便利的(在网上发布好的jsvascript库,即我们使用的//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js),我们再教程中使用了这种方式。主要是因为你可以随意的拷贝例子代码到你的机器上,而不用修改任何地方就可以正常的运行。但他们也有一些缺点:
- 为了性能,在cdns上的库都是进行了最小和最优处理后的dojo的发布版本,这样做的目的是尽可能的减小网络传输量。但这样会导致当你的代码出现什么问题的时候,很难调试。
- 使用cnds,需要要求使用你Web应用的用户使用的机器必须可以访问互联网,而有时候,特别是一些内部应用或涉密环境下是不现实的。
- It requires more effort to include your own custom modules.
- 当你发布你的Web应用时,你可能由于自己的特殊应用或者目标浏览器等一些原因,需要根据自己的情况修改一些配置或代码。
通过下面的步骤,你可以获取dojo的源码,并在此基础上开发自己的项目:
1.Download Dojo - 点击该链接,在打开的网页底部可以看到下载dojo源码的链接。如果你熟悉git或者gitHub,你可以直接从github上下载源码。
2.解压dojo的压缩包,拷贝到你的工程中,如下所示:
1 demo/ 2 myModule.js 3 dojo/ 4 dijit/ 5 dojox/ 6 util/ 7 hellodojo.html
3.把原来加载cdn上dojo.js的代码换成加载本地dojo.js的代码。
1 <script src="dojo/dojo.js"></script>
4.更新你的dojo模块包配置代码
1 var dojoConfig = { 2 async: true, 3 baseUrl: '.', 4 packages: [ 5 'dojo', 6 'dijit', 7 'dojox', 8 'demo' 9 ] 10 };
获取帮助
每当你感到困惑或遇到棘手的问题时,你要知道你不是一个人。志愿者通过Email(dojo-interest mailing list)、交互聊天(#dojo on irc.freenode.net)的方式为你提供帮助。如果你在我们提供的资源中发下错误,或者有歧义、令人难以理解的地方,反馈连接地址就在本页的下部,你可以通过该方式让我们知道。
如果你需要紧急或隐私的帮助,或者有我们志愿者也没有解决掉的问题,我们可以提供商业技术支持(commercial Dojo support)或培训(training workshops)。
下一步要做什么
使用Dojo Toolkit就像添加一个脚本标签或者加载几个模块一样简单。但dojo有着巨大的广度和深度,而现在我们只是接触到了其皮毛。根据你的需求,有好几条路径可以让你学习本系列教程。
- 如果你以前使用过DOJO,现在只是想更深入的了解ADM知识,或者了解最新改变的一些概念,那么你可以看下现代dojo(Modern Dojo)。如果你是想在已有的网站应用上添加一个特色和效果,那么你可以看Using dojo/query、Events with Dojo、effects 和animations 教程。
- 如果你想在你的页面上加上Ajax应用,可以看Ajax with Dojo教程。
- 如果你希望在你的页面或Web应用上整合富客户端应用的小部件,可以查看Creating Template-based Widgets 以及 tutorial series on Dijit widgets。
- 如果你正想学习复杂web应用的架构设计或者想了解DOJO提供的强大的功能,可以查看Core Concepts。
- 如果你的目标是移动应用,那么可以查看Getting Started with dojox/mobile。
无论你的目的是什么,dojo提供了一套行业领先的开源公里,它可以帮助我们在开发项目时达到事半功倍的效果。We look forward to seeing what you come up with!