Dojo
解決跨瀏覽器問題的工具包
Dojo是一個用javascript語言實現的開源DHTML工具包。它是在幾個項目捐助基礎上建立起來的(nWidgets,Burstlib,f(m)),這也是為什麼叫它a"unified"toolkit的原因。Dojo的目標是解決開發DHTML應用程序遇到的那些,長期存在、歷史問題(historical problems with DHTML)。跨瀏覽器問題。
Dojo能夠讓你更容易使Web頁面具有動態能力,或者在任何能夠穩定支持JavaScript語言的環境中發揮作用。
Dojo
把文件解壓縮到你的伺服器或測試目錄。這裡假設把文件解壓到 /js 下面,當做完以上步驟后,會出現如下圖的目錄結構。
在HTML頁面上添加JS引用
至此,安裝完成,DOJO的詳細使用方法,請參考DOJO官方文檔。
在2004年初, Alex Russell (netWindows的原作者)開始在Informatica公司內尋找一個在DHTML項目的一個合作者。這個過程中,許多DHTML社區的成員都被他聯繫到了。這些溝通最終引出了一封題為“宣傳DHTML的未來”的郵件。David Schotzler, Dylan Schiemann也與同年加入了Informatica公司。所以Dojo的最初的代碼是有Alex和Dylan在Informatica的支持下寫的。在Dojo早期,有許多成員都積極參與了開發,並逐漸形成了dojo今天的方向,他們是Joyce Park, Tom Trenka, Mark Anderson, Leonard Lin (最初提議用Dojo這個名字的人), Aaron Boodman, Simon Willison, Cal Henderson, and Dan Pupius.
社區成員們最初幾個月在ng-html郵件列表上討論了關於授權協議,項目名稱,編碼規範,構建工具,伺服器配置和用戶需求之後,真正的工作開始了,dojo基金會也宣告成立。基金會是一個501實體,用來保管項目代碼和知識產權,今天基金會也資助其他一些項目。dojo的貢獻者來自超過60個開發者,許多的公司,主要的用戶包括IBM,AOL, Sun, SitePen, Bloglines, Google, Nexaweb。
Dojo有以下的特徵:
1、利用Dojo提供的組件,你可以提升你的web應用程序可用性、交互能力以及功能上的提高。
2、也可以更容易的建立互動的用戶界面。同時Dojo提供小巧的動態處理工具。
3、利用它的低級API和可兼容的代碼,能夠寫出輕便的、單一風格(複雜)的JavaScript代碼。Dojo的事件系統、I/O的API以及通用語言形式是基於一個強大編程環境。
4、通過Dojo提供的工具,你可以為你的代碼寫命令行式的單元測試代碼。
5、Dojo的擴展包能夠使你自己的代碼更容易維護,耦合性更低。
Dojo通過很少的代碼完成了以上的功能。當你寫腳本時,只需要包含很少的js文件,也可以選擇的(包含)下載dojo提供的龐大的功能。
目前的最新版本:1.10
Dojo 1.5.0於2010年7月15日正式發布。此次發布的1.5.0版是dojo的第11個主要版本。此次發布包括了許多更新,具體包括:
新的用戶界面
新版本的Dojo提供了許多重大的界面改進,使用了新的Claro主題。Claro主題為Dojo的用戶界面庫Dijit提供了現代,專業的界面風格。這一主題包含了許多漸變透明背景,陰影以及CSS動畫特效(在WebKit和基於Mozilla的瀏覽器中可用)
新的主題體現了“簡單好用”的設計原則,並且極大的簡化了了用戶自己定製主題CSS的難度。因此用戶可以很容易的創建出屬於自己的風格,比如留白和色彩,而不用去設計新的背景圖片。與此同時,這些新的風格都被應用到了不斷增長的UI控制項之中。
新版的Dojo還提供了門戶網站布局機制,例如“personalized Orange home page ”。用戶可以快速創建自定義的應用界面。新版的Dojo中還對矢量圖形,圖表控制項和繪圖控制項做了許多增強,包括新的主題,漸變填充等。新的dojox.gfx(圖形圖象包)在現有的支持SVG,VML,Canvas,Flash和Silverlight之外增加了針對SVGWeb的支持。因此你的圖形代碼可以根據瀏覽器而自動選擇合適的底層引擎獲得最大效率,同時也可以最大限度的保證瀏覽器兼容性。
穩定,兼容的Dojo 核心
Dojo core( 核心庫) 一直非常穩定,因此從以前版本的Dojo 升級會非常順利,同時新版的Dojo core 也做了許多改進。新增加了dojo.Stateful API , 改進了dojo.Deffered API ,新增加了一種基於“承諾機制” api 。
簡而言之,Dojo core 核心庫提供了你構建Web 應用必須的幾乎所有基礎功能。
Dojo 中支持許多HTML5 的特性,其中有些特性的加入甚至早於任何瀏覽器對它們的支持,例如本地存儲。針對HTML5 的新功能,Dojo的策略是儘可能的包裝瀏覽器的功能,修正瀏覽器功能的小錯誤,增加API 的功能,簡化用法,並且對舊版本的瀏覽器提供一種兼容的方案。其他功能的增強還包括,所有基於文本框的控制項都增加了佔位提示文本,新的dojox.style 擴展 用於支持CSS 轉換,本地存儲,富文本編輯器,多文件的上傳,圖形API 對Canvas 和SVG 的支持。
Dojo 移動
移動應用開發領域的發展飛速,其變化演進的速度遠遠超出了我們對Dojo 核心保持穩定的承諾。因此在Dojo中有許多新的計劃正在積極進行中,目標是解決開發移動應用的時的各種難題。我們希望能夠同時解決兩種移動應用的類型:一種是移動的Web應用(運行在瀏覽器中),另一種是本地安裝的移動應用,但其中嵌入瀏覽器。下面一系列的新計劃或項目正在開展中,有些屬於Dojo工具包,有些則屬於Dojo 基金會:
dojox.mobile : 輕量級的移動應用組件
dojox.mobile.app : 移動應用開發框架
embedjs : 為移動應用優化的Dojo API
TouchScroll : 為WebKit 移動版定製的滑動抽象層
wink : 移動應用程序工具包(wink 是一個新加入dojo 基金會的項目)
瀏覽器支持
Dojo 支持幾乎所有現代的瀏覽器,官方正式支持並經過測試的瀏覽器包括: Chrome 5, Firefox 3.5 and 3.6;Internet Explorer 6, 7, and 8; Opera 10.6 (Dojo Core only); Safari 4.1and 5. 其他的瀏覽器版本雖然未經官方正式聲明支持,在絕大多數情況下Dojo 也可以在上面運行的很好。
性能和穩定性
Dojo 始終是性能評價最好的幾個Ajax 工具包之列,我們還提供了工具來幫助你擴展的應用程序去提升性能。不管你使用哪種開發工具包都有可能碰到性能問題,而Dojo 的社區的存在以及Dojo 背後的許多的廠商都會幫助你診斷和解決你所遇到性能問題。
整合與集成
無論你曾使用過哪種HTTP 兼容的伺服器端環境: Zend Framework, Spring, Persevere, Node,Narwhal, cometD-Jetty, DWR, Compuware Uniface, Ruby on Rails, Django,WebSphere, Apache, IIS, Dojo 都很容易與這些框架或技術進行集成。
Dojo 也提供了與Adobe AIR 1.5、 2.0 , Appcelerator Titanium, PhoneGap 的集成,並且提供了與各種開發環境的集成介面包括: aptana studio, Komodo, Elicpse 等等。
文檔與技術支持
Dojo 官方站點有完整的文檔,而活躍的社區論壇為用戶提供技術支持。如果需要職業的支持與諮詢,Sitpen 是一家會為你提供Dojo 技術服務與諮詢的公司。
現在開始下載並試用Dojo1.5 吧,告訴我們你的感受,也告訴我們你用Dojo 構建了哪些了不起的應用!
Dojo 基金會
Dojo 工具包是Dojo 基金會的一部分。在Dojo 工具包之外,基金會迎來了3 個新項目的加入 Zazl , AnimeJ , 和wink . 基金會的其他項目cometD-Jetty 發布了2.0 版本,而 Persevere 2.0 beta 版將於2010年夏發布。
------------舊版信息----------
請大家下載dojo 0.3.1, 以下的說明均針對此版本
1: 把Dojo加入到我們的Web程序中
1.1 標誌
djConfig是Dojo里的一個全局對象, 其作用就是為Dojo提供各種選項, isDebug是最常用的屬性之一, 設置為True以便能夠在頁面上直接看到調試輸出, 當然其中還有些屬性與調試有關, 這裡就不啰嗦了
1.2 引用 dojo 的啟動代碼
你就把這些代碼當成是java的import語句或C#中的using語句一樣, 如果你不require的話, 而模塊本身又沒有整合在dojo.js中, 是會出現腳本錯誤的喔
2. 針對不同需求提供的預整合包
Dojo本身是由許多模塊所組合而成的, 但是由於用戶需求的多樣性, dojo針對不同的需求而提供了不同的版本, 用戶在下載dojo的時候就看見可以選擇很多的版本, 比如Ajax版和Widget版, 每個版本最重要的區別就在於dojo.js文件, 但是除此之外, 每一個版本都是全功能的, dojo.js根據版本的不同而整合進了不同的模塊
3. 直接獲取Dojo的最新源代碼
......
比如: 模塊"dojo.html"包含了一系列的函數, 比如dojo.html.getContentBox(), 模塊"dojo.dnd"包含了一系列的HtmlDragObject的類
注意名稱約定, 函數的首字母為小寫字母,類的首字母為大寫
模塊也可以稱之為"命名空間"
包
在多數情況下, dojo的模塊只需要定義在一個文件就可以了, 但有時, 一個模塊可能劃分到多個文件, 比如: 模塊dojo.html, 本來是定義在一個文件中, 可是由於功能的增強, 文件逐漸變大, 我們不得不將其拆分為多個文件, 這主要是為性能考慮, 以便瀏覽器可以只下載其需要用到的代碼, 不幸的是其實現細節對於dojo的用戶看起來不那麼透明, 你必須知道你想要用到的功能到底是包含在哪個文件, 然後才能require並使用它,這樣的每一個文件都稱之為一個包
Dojo讓你更容易使web頁面具有動態能力,或在任何穩健的支持javascript語言的環境中發揮作用。
a、利用dojo提供的組件,你可以提升你的web應用程序可用性、交互能力以及功能上的提高;
b、你也可以更容易的建立degradeableuserinterfaces??,dojo提供小巧的widgets,animatetransitions;
c、利用它的低級APIs和可兼容的代碼,寫出輕便的、單一風格(複雜)的javascript代碼,Dojo的eventsystem,I/OAPIs,and generic language enhancement form the basis of a powerful programming environment.
d、通過Dojo提供的工具,你可以為你的代碼寫命令行式的單元測試代碼。
e、the Dojo package system使你自己的代碼更容易維護,耦合性更低。
Dojo通過很少的代碼完成了以上的功能。(以後可能我詳細說說dojo的packagesystem,只需要三個js文件)。當你寫腳本時,只需要包含很少的js文件(大小)。也可以選擇的(包含)下載dojo提供的龐大的功能。Dojo provides Multiple Points Of Entry,Interpreter Independence,Forward Looking APIs,and focuses on Reducing Barriers To Adoption.
dojo試圖建立一種新的標籤語言DojoML。目標是,在DojoML和javascript腳本語言不變的情況下,用不同的render方式展示數據,Renderingsmaybemadeavailableinseveralrenderingcontexts(suchasSVG,orperhapseventhedesktoporFlash)。(比較美好啊)更進一步,theDojoML剖析器可以接受html和svg為輸入,容易的建立DegradeableResponsiveApplications
djConfig是dojo內置的一個全局設置對象,其作用是可以通過其控制dojo的行為
首先我們需要在引用dojo.js前聲明djConfig對象,以便在載入dojo.js的時候才能夠取得所設置的值,雖然在0.3版本以後dojo支持在載入後設置,但是強烈建議你把聲明djConfig的代碼作為第一段script
一個完整的djConfig對象定義如下(值均為dojo的默認值)
vardjConfig={
isDebug:false,
debugContainerId:"",
bindEncoding:"",
allowQueryConfig:false,
baseScriptUri:"",
parseWidgets:true
searchIds:[],
baseRelativePath:"",
libraryScriptUri:"",
iePreventClobber:false,
ieClobberMinimal:true,
preventBackButtonFix:true,
};
isDebug是一個很有用的屬性,顧名思義,如果設置為真,則所有dojo.Debug的輸出有效,開發時應該設置為true,發布時應該設置為false.
debugContainerId同樣也是與調試有關的,如果不指定的話,調試信息將會直接利用document.write輸出,這樣可能會破壞頁面的整體布局,所以你可以指定任何一個可以作為容器的html元素的id作為調試信息輸出容器
allowQueryConfig,這個屬性指明dojo是否允許從頁面url的參數中讀取djConfig中的相關屬性,當值為true時,dojo會優先從url參數中讀取djConfig的其他屬性,比如:http://server/dojoDemo.htm?djConfig.debugContainerId=divDebug
baseScriptUri,一般不需要設置,dojo會自動根據你引用dojo.js的路徑設置這個值,比如,,自動獲取的值便是../dojo/
ps:如果你有多個工程需要同時引用dojo.js的話,建議也把dojo當作一個獨立的工程,引用的時候採用絕對路徑就可以了
parseWidgets,這個是可以控制dojo是否自動解析具有dojoType的html元素為對應的widget,如果你沒有使用任何Widget,建議設置為false以加快dojo的載入速度
searchIds,這是一個字元串數組,定義了所有需要解析為widget的html元素的ID,如果ID不在其中的html元素是不會被解析的,當數組為空數組時,則所有具有dojoType的元素都會被解析
還有一個bindEncoding,是用來設置默認的bind請求的編碼方式
至於其它的屬性,不是用處不大,就是不知道有什麼作用
在實際開發中,可以把djConfig的定義放在一個js文件里,並將其作為第一個引用的js文件,這樣應該是最方便的。
這裡所說的基礎對象和方法是指的不Require任何包就能夠調用的對象和方法
在開始前,介紹一下js里的匿名函數,這個在閱讀dojo的源代碼的時候,會發現到處都有匿名函數
;(function(){
alert(123);
})();
//前面的分號是一個空語句,是可以不要的匿名函數。一個匿名函數就是一個沒有名字的函數。可以認為他們是一次性函數。當你只需要用一次某個函數時,他們就特別有用。通過使用匿名函數,沒有必要把函數一直放在內存中,所以使用匿名函數更加有效率。當然你也可以根本不定義函數,但是使用匿名函數可以把你的代碼分段,就像C#中的#region一樣
dojo.byId
如果有多個元素具有指定的id,則返回的是一個集合
UsageExample:
dojo.byId("divTest");
dojo.byId("divTest",document);
dojo.byId(document.getElementById("divTest"));
dojo.version
dojo的版本,可以取得major,minor,patch,flag和revision
這個對象沒什麼太大用處,除非你要根據dojo的版本選擇執行你的代碼
dojo.raise
??拋出一個異常
dojo.errorToString
??將異常轉換為字元串
??UsageExample:
try
{
dojo.raise("列印失敗",newError("文件不存在"));
}
catch(e)
{
alert(dojo.errorToString(e));
}
dojo.render
??系統環境對象
dojo.rendere返回browser,說明是工作在瀏覽器下
dojo.render.ver返回4,似乎沒什麼用
dojo.os.win返回true說明操作系統是Windows
dojo.os.linux返回true說明操作系統是Linux
dojo.os.osx返回true說明操作系統是MacOS
dojo.html返回true說明瀏覽器是InternetExplorer
dojo.html.opera返回true說明瀏覽器是Opera
dojo.html.khtml返回true說明瀏覽器是Konqueror
dojo.html.safari返回true說明瀏覽器是Safari
dojo.html.moz返回true說明瀏覽器是MozillaFireFox
dojo.svg.capable返回true說明瀏覽器支持svg
dojo.vml.capable返回true說明瀏覽器支持vml
dojo.swf.capable返回true說明瀏覽器支持swf
dojo.swt.capable返回true說明瀏覽器支持swt(IBM開發的StandardWidgetToolkit)
如果dojo.html為true的話
dojo.html50返回true說明瀏覽器是IE5.0
dojo.html.55返回true說明瀏覽器是IE5.5
dojo.html.60返回true說明瀏覽器是IE6.0
dojo.html.e70返回true說明瀏覽器是IE7.0
dojo.addOnLoad
可以載入指定函數到window.load時執行,好處就是可以很方便的在window.load時執行多個函數
UsageExample:
dojo.addOnLoad(init);//init是一個函數
dojo.addOnLoad(myObject,init);//init是myObject對象的一個方法
dojo.require
如果你想調用一個模塊的對象的時候,你應該首先用dojo.require來請求這個模塊,dojo會根據你的請求自動取得相應的js文件,並載入到內存中,這樣你才能調用或創建其中的對象
dojo會自動維護已載入的模塊列表,所以是不會重複載入模塊的
UsageExample:
dojo.require("dojo.event");
dojo.requireIf=dojo.requireAfterIf
可以根據指定的條件來決定是否載入指定的模塊
UsageExample:
dojo.requireIf(dojo.htmle,"dojo.html");//如果dojo.html.為true,才會載入dojo.html模塊
dojo.provide
除非你要開發自己的模塊,不然是用不到這個方法的,你可以這句看成是向系統註冊這個模塊名稱。
UsageExample:
dojo.provide("dojo.custom");
dojo.exists
判斷指定對象是否具有指定名稱的方法
UsageExample:
dojo.exists(dojo,"exists");//willreturntrue
dojo.hostenv.getText
返回指定url的內容
PS:由於瀏覽器的安全限制,因此只能用於取得同域名的url的內容,否則會報告許可權不夠
UsageExample:
aSync=false;//同步,確保返回內容不為null
silent=true;//不拋出錯誤
s=dojo.hostenv.getText("http://www.googcom/",aSync,silent);//返回Google的首頁的HTML
alert(s);
dojo.debug
輸出調試信息,如果在djConfig中指定了debugContainerId,則輸出到指定的console容器中,否則直接document.write。
所有的調試信息均以DEBUG:開頭
UsageExample:
dojo.debug("這是調試信息");
dojo.hostenv.println
與dojo.debug類似,不同的是,輸出內容沒有DEBUG:
UsageExample:
dojo.hostenv.println("這是一般的輸出信息");
dojo.debugShallow
輸出指定對象的全部信息(Shallow說明並不會遍歷到下一級別的對象屬性)以供調試
UsageExample:
dojo.debugShallow(dojo.render.html);
1.編譯合適的dojo文件。
dojo十分“巨大”,而且有很多文件是最終用戶不需要使用的。
默認情況下的dojo.js比較大,有200多k,但是如果自定義進行編譯之後可能只有10多k。
而且將常用的模塊編譯到dojo.js也能提高效率。
dojo的載入順序如下:
1).瀏覽器載入dojo.js
dojobootstrpcode
dojoloader
(optionally)frequentlyusedmodules
2).dojo.js激活Dojo對象,動態的載入其他的module,如果模塊已經載入,那麼將不會再一次重新載入。
dojo提供了一系列典型的編譯方案可以選擇。
dojo的編譯可以減少文件的下載數目,可以使文件大小顯著的減少。
2.減少widget的使用。
每載入一個dojo的widget都需要額外的時間,所以當然使用越少dojo控制項,速度就越快。
3.使用新版本的dojo,建議1.0以上。
新版本對性能進行了優化,減少了bug,所以盡量選用新的穩定版本。
4.減少htmltag,每增加一個tag,性能的負擔就越重,比如
使用xxxxxxx
就不如用xxxxxxx
5.優化widget的載入
dojo在頁面載入的時候將分析整個HTML文件,自動載入指定的內容為dojo控制項。即使你沒有定義任何dojo控制項。所以優化widget的控制項能夠顯著的提升一個頁面載入的性能。
如果頁面載入花費的時間比較多,你覺得不正常,可以用Firebug看看是不是頁面載入的時候花費很多時間在dj_load_init()或者modulesLoaded()這些地方,這些都是明顯的信號表明我們需要留意widget的載入問題。
dojo提供了多種方式來控制widget的載入。其中最重要的就是它提供了跳過所有widget解析的方法,只需要加入下面的代碼到dojo.js引入之前:
djConfig={parseWidgets:false,searchIds:[]};
djConfig={parseWidgets:false,searchIds:[]};
那麼如果需要解析一部分widget怎麼辦呢?下面的方法可以指定需要解析那些widget。只需要將需要解析的widget的id放到searchIds:
djConfig={parseWidgets:false,searchIds:["info","confirmation"]};
djConfig.searchIds.push("from_date");
上面的代碼一共解析了3個dojowidget,其中前兩個直接放到searchIds,而第三個則動態的加入到searchIds。
如果你不喜歡searchIds的方式,還有一種方式提供選擇,給控制項加上parseWidgets='false'屬性:
Dojowidgetparser將不會運行到這裡,因為我們已經告訴他忽略這裡。
通過上面的方式,相信你的dojo性能能夠得到顯著的提升,如果仍然達不到性能要求,那麼可能你只能放棄dojo,或者讓客戶進行機器的升級了。。