在本教程中我们将会探索Dojo工具包提供的JavaScript特效,这些特效将给你的页面和网站创造酷炫的效果!
难度: 初学者
所需Dojo版本: 1.6
作者: Bryan Forbes
译者: feijia ([email protected])
在前面的一系列教程中,我们已经学习了如何使用并操作DOM节点,处理DOM事件。但是当我们在对DOM节点进行操作时,有些转换会显得突兀:例如删除一个节点,在用户看来它就会在页面上突然消失,有时这种页面上的突然变化会误导用户。使用Dojo提供的特效工具,我们可以构建出更加连贯的用户体验,并且让我们的应用程序显得更加精致和完美。如果我们进一步使用dojo.fx包里的更多功能,我们能够把一系列特效串联起来,创造出非常酷的动态用户体验。
最常见的一种特效就是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
另一种常见特效是擦除效果: 它实际上是指改变一个节点的高度,而让其内容逐渐显示或者消失。效果有点类似与雨刷在挡风玻璃上划过留下的痕迹。
请看下面的示例代码
<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处理函数之后被调用。因此作为参数传入的方法保证了我们的处理函数可以被最先执行。
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/