Hello Dojo!(翻译)

时间:2022-05-20 18:23:04

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模式的模块装载器,该装载器定义了requiredefine两个全局函数。后面我们有专门介绍AMD的文章。作为初始DOJO,我们只要知道require函数是加载一个模块以使用它们,而define函数是用来定义我们自己的模块。 一般情况下,每个模块都对应着一个javascript物理文件。

dojo/dom和dojo/dom-construct就是dojo为操作html DOM定义的一些基础模块,下面让我们看下如何加载这些模块,并使用它们。

 <!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.10.4/dojo/dojo.js"
data-dojo-config="async: true"></script> <script>
require([
'dojo/dom',
'dojo/dom-construct'
], function (dom, domConstruct) {
var greetingNode = dom.byId('greeting');
domConstruct.place('<em> Dojo!</em>', greetingNode);
});
</script>
</body>
</html>

require函数的第一个参数(14-17行)是模块标识列表,用来标识你想加载哪些模块。一般情况下,这些模块的标识都映射了定义模块的Javascript文件名。如果你下载了dojo的源码发布包,打开dojo文件夹,你会在该文件夹下发现dom.jsdom-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

在该文件中输入一下代码:

 define([
// The dojo/dom module is required by this module, so it goes
// in this list of dependencies.
'dojo/dom'
], function(dom){
// Once all modules in the dependency list have loaded, this
// function is called to define the demo/myModule module.
//
// The dojo/dom module is passed as the first argument to this
// function; additional modules in the dependency list would be
// passed in as subsequent arguments. var oldText = {}; // This returned object becomes the defined value of this module
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];
}
};
});

AMD的define函数接受的参数和reqiure函数接受的参数类似,都是模块标识数组以及一个回调函数。AMD加载器保存了回调函数返回的值,回调函数返回的值就是该自定义模块提供的功能。当其他的代码通过require函数或define函数加载该模块候,都可以调用该模块定义的这些功能,即回调函数返回的一些函数等。

CDN的使用

通过Dojo加载本地自定义的一些模块需要一些额外的配置。更详细的内容会再后面的章节中介绍。

下面把Hellodojo.html中的代码更新为以下内容。

 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tutorial: Hello Dojo!</title>
</head>
<body>
<h1 id="greeting">Hello</h1>
<!-- configure Dojo -->
<script>
// Instead of using data-dojo-config, we're creating a dojoConfig
// object *before* we load dojo.js; they're functionally identical,
// it's just easier to read this approach with a larger configuration.
var dojoConfig = {
async: true,
// This code registers the correct location of the "demo"
// package so we can load Dojo from the CDN whilst still
// being able to load local modules
packages: [{
name: "demo",
location: location.pathname.replace(/\/[^/]*$/, '') + '/demo'
}]
};
</script>
<!-- load Dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script> <script>
require([
'demo/myModule'
], function (myModule) {
myModule.setText('greeting', 'Hello Dojo!'); setTimeout(function () {
myModule.restoreText('greeting');
}, 3000);
});
</script>
</body>
</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加载完毕后才会被调用。

  require([
'dojo/dom',
'dojo/domReady!'
], function (dom) {
var greeting = dom.byId('greeting');
greeting.innerHTML += ' from Dojo!';
});

上面的例子是在greeting节点上加载了一些文本,而完成这些工作必须要等DOM节点加载完毕才能执行。请注意,代码在加载dojo/domReady模块时,后面加了!符号。如果没有该符号,dojo会把该模块当成普通的AMD模块处理。

在一些情况下,我们调用例如dojo/domReady这样的模块,不是为了调用其定义的功能,而是另有他用。但AMD加载器对此一无所知,它依旧把每个模块作为参数传递给回调函数。所以有一些你不需要调用的模块标识,可以放在模块标识数组的最后面,在回调函数中,就可以忽略这些模块。

后面的文章还会对Dojo操作DOM有具体的描述。

添加视觉效果

现在我们可以通过添加一些动画效果,让我们的例子看起来更加生动活跃一些。我们可以加载dojo/fx模块来给我们的页面添加效果。下面我们通过dojo/fx模块的slideTo函数给greeting节点添加渐变动画。

 require([
'dojo/dom',
'dojo/fx',
'dojo/domReady!'
], function (dom, fx) {
// The piece we had before...
var greeting = dom.byId('greeting');
greeting.innerHTML += ' from Dojo!'; // ...but now, with an animation!
fx.slideTo({
node: greeting,
top: 100,
left: 200
}).play();
});

如上代码所示,我们又增加了一个队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的压缩包,拷贝到你的工程中,如下所示:

 demo/
myModule.js
dojo/
dijit/
dojox/
util/
hellodojo.html

3.把原来加载cdn上dojo.js的代码换成加载本地dojo.js的代码。

 <script src="dojo/dojo.js"></script>

4.更新你的dojo模块包配置代码

 var dojoConfig = {
async: true,
baseUrl: '.',
packages: [
'dojo',
'dijit',
'dojox',
'demo'
]
};

获取帮助

每当你感到困惑或遇到棘手的问题时,你要知道你不是一个人。志愿者通过Email(dojo-interest mailing list)、交互聊天(#dojo on irc.freenode.net)的方式为你提供帮助。如果你在我们提供的资源中发下错误,或者有歧义、令人难以理解的地方,反馈连接地址就在本页的下部,你可以通过该方式让我们知道。

如果你需要紧急或隐私的帮助,或者有我们志愿者也没有解决掉的问题,我们可以提供商业技术支持(commercial Dojo support)或培训(training workshops)。

下一步要做什么

使用Dojo Toolkit就像添加一个脚本标签或者加载几个模块一样简单。但dojo有着巨大的广度和深度,而现在我们只是接触到了其皮毛。根据你的需求,有好几条路径可以让你学习本系列教程。

无论你的目的是什么,dojo提供了一套行业领先的开源公里,它可以帮助我们在开发项目时达到事半功倍的效果。We look forward to seeing what you come up with!