Dojo學習筆記(一):Hello Dojo!


歡迎來到Dojo世界!在這篇文章中你將會學習到如何加載Dojo以及探索Dojo的一些核心功能。你還會了解Dojo的基於AMD的模塊架構,探索如何加載額外的模塊來增加功能到您的Web站點或應用程序,並找出在出錯的時如何得到幫助。

讓我們開始吧

開始學習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 EffectsAnimations

如何進一步學習Dojo?

學習Dojo ToolKit和添加一個標簽以及引用模塊一樣簡單,但功能及其廣泛和強大的Dojo意味着我們只能勉強掌握Dojo表面的皮毛。依據你的需求,我們提供了一系列不同方向的文章:

無論你想要什么結果,Dojo提供了業界領先的開放源代碼工具,可以幫助您完成您的項目在較短的時間以驚人的結果。我們期待着看到你了!



本系列文章翻譯至Dojo官網,旨在學習Dojo並提高英語閱讀能力,有翻譯錯誤的地方請多指正!謝謝


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM