在本教程中我們將會探索Dojo工具包提供的JavaScript特效,這些特效將給你的頁面和網站創造酷炫的效果!
難度: 初學者
所需Dojo版本: 1.6
作者: Bryan Forbes
譯者: feijia (tiimfei@gmail.com)
在前面的一系列教程中,我們已經學習了如何使用並操作DOM節點,處理DOM事件。但是當我們在對DOM節點進行操作時,有些轉換會顯得突兀:例如刪除一個節點,在使用者看來它就會在頁面上突然消失,有時這種頁面上的突然變化會誤導使用者。使用Dojo提供的特效工具,我們可以構建出更加連貫的使用者體驗,並且讓我們的應用程式顯得更加精緻和完美。如果我們進一步使用dojo.fx包裡的更多功能,我們能夠把一系列特效串聯起來,創造出非常酷的動態使用者體驗。
漸入和漸出效果 (Fade)
最常見的一種特效就是DOM節點的漸入與漸出(淡入與淡出)。這個效果在網頁上會經常用到,因此dojo把它包含Dojo的基礎包中。(譯者:表示你不需要使用dojo.require引用任何包)我們可以使用這個效果讓節點在頁面的出現和消失顯得連續和平滑。 下面是使用dojo建立漸入漸出效果的範例程式碼:
<button id="fadeOutButton">Fade block out</button><button id="fadeInButton">Fade block in</button> <div id="fadeTarget" class="red-block"> A red block</div><script> dojo.ready(function(){ var fadeOutButton = dojo.byId("fadeOutButton"), fadeInButton = dojo.byId("fadeInButton"), fadeTarget = dojo.byId("fadeTarget"); dojo.connect(fadeOutButton, "onclick", function(evt){ dojo.fadeOut({ node: fadeTarget }).play(); }); dojo.connect(fadeInButton, "onclick", function(evt){ dojo.fadeIn({ node: fadeTarget }).play(); }); });</script>
真正製造漸入漸出方法的代碼只需要一行,就是dojo.fadeOut 和dojo.fadeIn。 Dojo裡所有的動畫特效函數都只接受一個參數對象,該參數對象包含了一系列屬性來設定所需動畫效果。其中 最重要的屬性之一就是 node。 node屬性值是一個DOM節點或者是一個DOM 節點的ID (字串)。 另一個參數 duration,則指定了這個效果的播放要持續的時間,單位是毫秒。如果不指定duration,則預設的播放時間是350毫秒。當然不同的動畫效果有不同的參數,不過對於淡入淡出特效而言,這兩個參數就足夠了。
Dojo的動畫特效函數傳回值是一個dojo.Animation 對象。這個對象有幾個方法: play, pause, stop, status 和gotoPercent 從名字可以看出這幾個方法是用來控制動畫效果的播放的。 動畫對象剛建立時並不會立即播放,需要調用play方法才開始播放。
查看樣本:
http://dojotoolkit.org/documentation/tutorials/1.6/effects/demo/fade.html
擦除效果(Wiping)
另一種常見特效是擦除效果: 它實際上是指改變一個節點的高度,而讓其內容逐漸顯示或者消失。效果有點類似與雨刷在擋風玻璃上划過留下的痕迹。
請看下面的範例程式碼
<button id="wipeOutButton">Wipe block out</button><button id="wipeInButton">Wipe block in</button> <div id="wipeTarget" class="red-block wipe"> A red block</div><script> // Load the dojo.fx module dojo.require("dojo.fx"); // Don't forget, when using modules, wrap your code in a dojo.ready dojo.ready(function(){ var wipeOutButton = dojo.byId("wipeOutButton"), wipeInButton = dojo.byId("wipeInButton"), wipeTarget = dojo.byId("wipeTarget"); dojo.connect(wipeOutButton, "onclick", function(evt){ dojo.fx.wipeOut({ node: wipeTarget }).play(); }); dojo.connect(wipeInButton, "onclick", function(evt){ dojo.fx.wipeIn({ node: wipeTarget }).play(); }); });</script>
和fadeIn fadeOut不同,使用擦除函數需要先引用dojo.fx包。另一個需要注意的是我們在這個例子裡給目標節點“wipeTarget" 增加了一個css類wipe, 這個類設定了節點的height:auto, 這是因為wipeIn函數的效果是從節點的現有高度變化到其自然高度(即height:auto)
查看樣本
滑動
前面我們看到了淡入淡出和擦除效果,這兩個特效都不能改變節點在頁面上的位置。如果想要節點滑動起來,那麼就要使用dojo.fx.slideTo 。
滑動效果可以創造一種動態感,有時也用來表示某種載入進度。dojo.fx.slideTo函數可以在參數指定節點的目標位置(頁面上的left和top位置) 並把這個節點滑動到目標位置。
<button id="slideAwayButton">Slide block away</button><button id="slideBackButton">Slide block back</button> <div id="slideTarget" class="red-block slide"> A red block</div><script> dojo.require("dojo.fx"); dojo.ready(function(){ var slideAwayButton = dojo.byId("slideAwayButton"), slideBackButton = dojo.byId("slideBackButton"), slideTarget = dojo.byId("slideTarget"); dojo.connect(slideAwayButton, "onclick", function(evt){ dojo.fx.slideTo({ node: slideTarget, left: "200", top: "200" }).play(); }); dojo.connect(slideBackButton, "onclick", function(evt){ dojo.fx.slideTo({ node: slideTarget, left: "0", top: "100" }).play(); }); });</script>
查看樣本:
點擊開啟連結
動畫事件
前面我們提到過,Dojo裡的所有的動畫特效函數都會返回一個dojo.Animation對象。這個對象不僅提供了方法控制動畫的播放暫停,同時還提供了一系列的事件供我們監聽,從而使我們可以在動畫播放前,播放中,播放後做出不同的響應動作。最重要也是最常用的兩個事件是:beforeBegin 和 onEnd
下面我們看一段使用動畫事件的範例程式碼:
<button id="slideAwayButton">Slide block away</button><button id="slideBackButton">Slide block back</button> <div id="slideTarget" class="red-block slide"> A red block</div><script> dojo.require("dojo.fx"); dojo.ready(function(){ var slideAwayButton = dojo.byId("slideAwayButton"), slideBackButton = dojo.byId("slideBackButton"), slideTarget = dojo.byId("slideTarget"); dojo.connect(slideAwayButton, "onclick", function(evt){ var anim = dojo.fx.slideTo({ node: slideTarget, left: "200", top: "200", beforeBegin: function(){ dojo.style(slideTarget, { left: "0px", top: "100px" }); } }); //在動畫播放完成後將背景色設為藍色 dojo.connect(anim, "onEnd", function(){ dojo.style(slideTarget, { backgroundColor: "blue" }); }); anim.play(); }); dojo.connect(slideBackButton, "onclick", function(evt){ var anim = dojo.fx.slideTo({ node: slideTarget, left: "0", top: "100", beforeBegin: function(){ dojo.style(slideTarget, { left: "200px", top: "200px" }); } }); //在動畫播放完成後將背景色更改為紅色 dojo.connect(anim, "onEnd", function(){ dojo.style(slideTarget, { backgroundColor: "red" }); }); anim.play(); }); });</script>
這段範例程式碼裡我們注意到添加beforeBegin 和onEnd 這兩個事件的回調方法的方式不太一樣。beforeBegin 的處理方法直接作為參數傳遞給了slideTo函數。而onEnd是使用dojo.connect 串連的。這是因為對某些動畫特效beforeBegin處理函數是在對象建立時串連的,如果我們通過dojo.connect 來註冊我們的beforeBegin處理函數,則我們的處理函數會在該動畫自己的beforeBegin處理函數之後被調用。因此作為參數傳入的方法保證了我們的處理函數可以被最先執行。
查看樣本
鏈式調用(Chaining)
Dojo 動畫特效的強大之處還在於可以使用鏈式調用將許多不同的特效串聯起來執行.實際上通過監聽onEnd事件,我們就可以做到在前一個動畫執行之後再執行另一個動畫,但是這樣並不是很方便。而使用dojo.fx.chain我們可以非常簡單設定一系列的動畫連續執行。 讓我們再來看一個例子
<button id="slideAwayButton">Slide block away</button><button id="slideBackButton">Slide block back</button> <div id="slideTarget" class="red-block slide chain"> A red block</div><script> dojo.require("dojo.fx"); dojo.ready(function(){ var slideAwayButton = dojo.byId("slideAwayButton"), slideBackButton = dojo.byId("slideBackButton"), slideTarget = dojo.byId("slideTarget"); dojo.connect(slideAwayButton, "onclick", function(evt){ dojo.fx.chain([ dojo.fadeIn({ node: slideTarget }), dojo.fx.slideTo({ node: slideTarget, left: "200", top: "200" }), dojo.fadeOut({ node: slideTarget }) ]).play(); }); dojo.connect(slideBackButton, "onclick", function(evt){ dojo.fx.chain([ dojo.fadeIn({ node: slideTarget }), dojo.fx.slideTo({ node: slideTarget, left: "0", top: "100" }), dojo.fadeOut({ node: slideTarget }) ]).play(); }); });</script>
從這段代碼可以看到,我們使用 dojo.fx.chain方法,傳入一個由多個動畫特效組成的數組,並在chain方法返回的dojo.Animation對象上執行play,這一系列動畫將會逐一執行。
查看樣本
合并執行
chain方法使一系列動畫特效逐一執行,而dojo.fx.combine則可以讓一組動畫同時執行。 在前面的例子中,是先淡入,然後滑動,最後淡出。使用combine我們可以讓這三個效果同時執行。 combine方法會返回一個新的dojo.Animation對象代表合并後的新動畫。這個動畫對象的onEnd事件將在被合并的動畫全部都執行完成後被觸發。
<button id="slideAwayButton">Slide block away</button><button id="slideBackButton">Slide block back</button> <div id="slideTarget" class="red-block slide chain"> A red block</div><script> dojo.require("dojo.fx"); dojo.ready(function(){ var slideAwayButton = dojo.byId("slideAwayButton"), slideBackButton = dojo.byId("slideBackButton"), slideTarget = dojo.byId("slideTarget"); dojo.connect(slideAwayButton, "onclick", function(evt){ dojo.fx.combine([ dojo.fadeIn({ node: slideTarget }), dojo.fx.slideTo({ node: slideTarget, left: "200", top: "200" }) ]).play(); }); dojo.connect(slideBackButton, "onclick", function(evt){ dojo.fx.combine([ dojo.fx.slideTo({ node: slideTarget, left: "0", top: "100" }), dojo.fadeOut({ node: slideTarget }) ]).play(); }); });</script>
這個例子裡,我們通過combine把淡入效果和滑動效果同時執行。
通過使用chain和combine,我們可以用幾種簡單效果組合出很不錯的動畫特效。同時chain和combine的傳回值仍然是一個animation對象,也就是說它們還可以被進一步的串聯和合并,因此可以創造出非常精巧複雜的效果。
小結
使用Dojo的特效方法,你可以快速的給頁面加上有趣的動畫效果。dojo 基礎包中已經包含了淡入淡出方法dojo.fadeIn dojo.fadeOut,而通過require dojo.fx 你還可以使用擦除和滑動效果。結合chain和combine 這兩個組合方法,可以構建出進階的動畫效果。
當然如果你還想更進一步的控制動畫的效果,例如,像wipeOut一樣調整某個DOM節點的高度,但是又不把它完全縮減到0(完全擦除),或者通過動畫來調整背景色的漸層? Dojo提供了一個更加通用和強大的dojo.animateProperty對象來實現。 我們會在未來的教程中詳細介紹。
參考(譯者)
這個教程比較簡單,提供的樣本也是示意性質的。下面我找了一些使用dojo.fx 做出的比較複雜比較炫的特效樣本。 供讀者參考:
用dojo實現的複雜文本動畫效果:
http://gruppler.dojotoolkit.org/
畫面切分“阿凡達”特效:
http://demos.davidjs.com/avatar/