Hello Dojo ! 开始学习Dojo <4>

年前看完了dojo loader的文档,对源代码还没有完全看完,只是看了模块名解析的源代码。 现在直接进入到 Dojo的学习,建立起一个整体的框架。

Hello Dojo!

欢迎来到Dojo! 在这个教程里,你将学习到如何加载Dojo, 并且会开始解释它的核心功能。 你也将会学习至Dojo的基于AMD模式的体系结构。如何给你的网站或者应用通过加载额外的模块来添加额外的功能。 也教会你在错误发生时如何解决。

开始

开始使用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="http://ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojo/dojo.js"
            data-dojo-config="async: true"></script>
</body>
</html>

正常的, 一旦你加载完一个javascript库文件后,你将会得到这个库所有的方法, dojo之前是这样的,但在1.7版本后, dojo对源代码采用的是异步模块定义(AMD)格式, 允许整个应用程序的开发完全模块化。 采用AMD的原因是因为它是纯Javascript,支持浏览器,在应用程序部属时,支持 build工具对资源进行优化。

当dojo.js 被加载完成之后会又有什么是可用的呢? dojo.js 是一个AMD 加载器,它定义了两个全局的函数, require 和 define. 异步模块定义(AMD)你可以查看 AMD介绍教程. 学习完AMD介绍教程后,你会完全理解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="http://ajax.googleapis.com/ajax/libs/dojo/1.9.2/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('<i> Dojo!</i>',greetingNode);
        });
    </script>
</body>
</html>

require 的第一个参数(行14-17) 是一个你想加载的模块ids数组。 一般, 它们会直接映射到文件名, 如果你下载的了 Dojo的源码版本, 找到dojo文件夹,你可以看到 dom.js 及 dom-construct.js文件。

AMD loader 是异步加载的, 在javascript的异步操作是通过回调函数来实现。 所以在require的第二个参数(行17) 是一个回调函数。 在这个函数里,你可以使用加载到的模块。 AMD loader 将模块作为参数传递给回调函数(保持跟模块Ids数组中相同的排序)。 你可以随便定义回调函数内参数的名称。 但是为了一致性及可读性, 建议使用跟模块Id相同的名称。

在18-19行,你可以看到dom及dom-construct 模块通过DOM 节点的Id来获得一个节点的引用,并组织它们的内容。

* AMD loader 会自动加载请求模块的子依赖(模块定义中define,第一个数组参数), 所以你只需指定你要依赖的模块,其它的不需要管


定义一个AMD 模块

此时你已经通过一个例子了解模块的加载及使用。 为了定义及加载你自己的模块, 你将需要有一个http 服务器(localhost最好). 在包含有hellodojo.html文件夹个创建一个demo文件夹,在demo文件夹下创建一个myModule.js,文件结构如下:

demo/
    myModule.js
hellodojo.html

myModule.js 内容如下:
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 函数接受跟require相似的参数 - 模块依赖数组及一个回调函数。 AMD加载器保存回调函数的返回值来作为这个模块的值(返回值代表这个模块)。 所以其它代码通过require 或者define来加载这个模块, 将会获得这个返回值的引用。


CDN 使用

加载本地模块同时从CDN中的dojo需要一些额外的配置(配置Dojo AMD加载器和使用CDN的更多信息可以查看 AMD高级使用 CDN下模块教程,如下是更新后的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.9.2/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,用它来操作网页中的文本。 像你看到的, 定义和加载一个模块非常简单。 我们已经改变了dojo.js的 url,省略掉了协议部分(26行), 这样可以依据页面是使用什么协议(http或者https)来创建相对应的URL,以防在某些浏览器下混合使用双协议的内容产生安全警告。

在AMD模块下组织代码允许你创建可以浏览器下立即执行的模块化的Javascript源代码。并且容易调试。 AMD模块的变量都是使用局部作用域,避免全局命名空间的混乱和最快的找到变量(不用去查找所有作用域链中的变量)。AMD是一个多种实现(dojo loader,requireJs)的标准规范。 所以你可以不受限于其中的一种, AMD模块可以通过任何基于AMD规范的加载器来加载。

等待文档对象模型(DOM)

在开发web应用程序中,常见的一种情况是在执行代码前,你需要确保浏览器已经解析了 DOM. 为了达到这个目的,需要通过特殊的AMD模块来实现,称为 “插件”. 插件的请求像其它模块一样,只是需要在标识符的末尾加个一个"!" 感 叹号。 在任何require及define中的依赖中这个插件,它的callback在 DOM准备好前是不会被触发的。

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

查看DEMO

上面这个例子简单的给greeting元素添加文本 - 需要依赖于DOM已经加载好了(我们不需要在之前的代码使用,因为script元素是在 body后面被包含进来的。 DOM已经被加载了), 再次强调一下, 模块的标识符后面需要一个"!" ; 如果没有, dojo/domReady模块会像其它的模块那样提供简单的功能。

在一些情况下,像dojo/domReady,我们加载的模块仅需要附代的功能,而不需要引用它。 AMD 加载器没有办法知道这个, 它还是会给回调函数传递依赖数组中每个模块的引用, 所以不需要引用的模块,你只要将它们放到依赖数组的尾部。 然后在回调函数中省略掉不需要的模块就行。

更多的关于DOM操作的功能可以查看 Dojo DOM 函数教程.

添加视觉效果

现在可以给我们的例子添加一些动画,使它更加有生动。 其中dojo/fx模块我们可以用来给页面添加效果, 让我们通过dojo/fx的 slideTo方法来给greeting添加一个划动的效果。

require([
    'dojo/dom','dojo/fx',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();
});

查看 DEMO

更多的效果及动画可以查看 Dojo Effects Animations

使用Dojo 源代码

我们在教程的例子中使用CDNs,是因为你可以直接复制代码而不需要改变任何的东西。 虽然它很方便,但也有以下的劣势:

  • 从性能上来说, 它们是"build" 后的版本, 意思是每一个模块已经是最小化和调优过的。当你出现问题是,很难调试代码。
  • 需要你可以访问互联网,而许多情况下是不实际的。
  • 在包含你自己的定义的模块时,需要付出更多的努力(更多的执行步骤)
  • 如果你需要投放你的应用程序,你需要自己通过build工具来优化性能或者针对特定的浏览器, 你就不能通过CDN build来优化了。

按照以下的步骤开始获得和使用dojo源码:
  1. 下载Dojo - 在靠近页面的底部下载源代码版本。
  2. 解压文件到你的项目文件夹,结构如下:
demo/
    myModule.js
dojo/
dijit/
dojox/
util/
hellodojo.html
3. 加载本地的dojo.js,而不是 CDN:
<script src="dojo/dojo.js"></script>

4. 更新你的包配置
var dojoConfig = {
    async: true,baseUrl: '.',packages: [
        'dojo','dijit','dojox','demo'
    ]
};

获得帮助

当你遇到困惑或棘手的问题时,你并不孤单。 你可以通过 dojo-interest mailing list中的email地址或者 在线聊天 联系志愿者. 如果你发现了我们文档中的错误 或者有误解及困惑的地方, 可以通过所有文档最下方的返馈链接给我们返馈相关问题。

如果你有紧急或者保密的帮助,或者志愿者不能解决的问题时,可以通过 SitePen 来获得商业的支持.

下一步是什么?

入门的Dojo 非常简单,只是添加一个script 标签,及加载需要的模块。 但这只是dojo的皮毛。 依据你的需求, 以下有几种不同的学习路径:

不管你需要的是什么,Dojo提供了工业级的开源工具给你, 它可以帮你降低项目的时间,并获得意想不到的效果。

相关文章

我有一个网格,可以根据更大的树结构编辑小块数据.为了更容易...
我即将开始开发一款教育性的视频游戏.我已经决定以一种我可以...
我正在使用带有Grails2.3.9的Dojo1.9.DojoNumberTextBox小部...
1.引言鉴于个人需求的转变,本系列将记录自学arcgisapiforja...
我正在阅读使用dojo’sdeclare进行类创建的语法.描述令人困惑...
我的团队由更多的java人员和JavaScript经验丰富组成.我知道这...