原文地址:http://dojotoolkit.org/documentation/tutorials/1.7/effects/
难度:低
版本:1.7
在这个教程中,我们将了解一些dojo所提供了一点动态的效果,让我们的页面能更生动活泼。
开始
到目前为止,我们已经学会了如何管理和操作DOM节点,但做这些操作时,页面的表现会很生硬。如你删除一个节点,这个节点就实然的不见了,这可能会让用户疑惑。使用dojo提供的动态效果后会使一些操作的效果很平滑,能非常好的提高用户的交互性。
dojo有两个模块dojo/_base/fx和dojo/fx
- dojo/_base/fx提供了一些基础的效果,如animateProperty,anim,fadeIn,fadeOut
- dojo/fx提供了更多更高级的效果,包括chain,combine,wipeIn,wipeOut和slideTo
渐变
有一个效果我们以前已经用过了,那就是带有渐变效果的显示和消失,这个效果很常用,所有这个效果被放置于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> require(["dojo/_base/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) { var fadeOutButton = dom.byId("fadeOutButton"), fadeInButton = dom.byId("fadeInButton"), fadeTarget = dom.byId("fadeTarget"); on(fadeOutButton, "click", function(evt){ fx.fadeOut({ node: fadeTarget }).play(); }); on(fadeInButton, "click", function(evt){ fx.fadeIn({ node: fadeTarget }).play(); }); }); </script>
方法有一个对象参数。最重要的属性是node,这可以是DOM节点或ID值,别一个属性是duration,这决定了动画执行的时间,以毫秒记。默认值为350,还有另几个属性,但不是必须的。
动画方法返回的是一个dojo.Animation对象,这个对象有play,pause,stop,status,gotoPercent的这些方法。动画被创建了并不是马上就执行,它要你显示的使用play方法来执行。
擦除效果
另一个常见的效果就是擦除效果了。这种效果有点像车窗上的擦除效果,通常,这种效果表现出下拉,收起的动画。
<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> require(["dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) { var wipeOutButton = dom.byId("wipeOutButton"), wipeInButton = dom.byId("wipeInButton"), wipeTarget = dom.byId("wipeTarget"); on(wipeOutButton, "click", function(evt){ fx.wipeOut({ node: wipeTarget }).play(); }); on(wipeInButton, "click", function(evt){ fx.wipeIn({ node: wipeTarget }).play(); }); }); </script>
擦除动画方法被放置于 dojo/fx 模块中,在这个示例中,我们加入了一个wipe的class样式,因为,这种效果是通过操作元素的高度来实现的,加入了wipe是为了把元素的高度定义为自动
滑动
现在我们来实现滑动的效果。使用 fx.slideTo 来实现,直接看示例
<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> require(["dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) { var slideAwayButton = dom.byId("slideAwayButton"), slideBackButton = dom.byId("slideBackButton"), slideTarget = dom.byId("slideTarget"); on(slideAwayButton, "click", function(evt){ fx.slideTo({ node: slideTarget, left: "200", top: "200" }).play(); }); on(slideBackButton, "click", function(evt){ fx.slideTo({ node: slideTarget, left: "0", top: "100" }).play(); }); }); </script>
动画效果
通过上面的介绍你已经知道,动画方法将返回的是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> require(["dojo/fx", "dojo/on", "dojo/dom-style", "dojo/dom", "dojo/domReady!"], function(fx, on, style, dom) { var slideAwayButton = dom.byId("slideAwayButton"), slideBackButton = dom.byId("slideBackButton"), slideTarget = dom.byId("slideTarget"); on(slideAwayButton, "click", function(evt){ // Note that we're specifying the beforeBegin as a property of the animation // rather than using connect. This ensures that our beforeBegin handler // executes before any others. var anim = fx.slideTo({ node: slideTarget, left: "200", top: "200", beforeBegin: function(){ console.warn("slide target is: ", slideTarget); style.set(slideTarget, { left: "0px", top: "100px" }); } }); // We could have also specified onEnd above alongside beforeBegin, // but it's just as easy to connect like so on(anim, "End", function(){ style.set(slideTarget, { backgroundColor: "blue" }); }, true); // Don't forget to actually start the animation! anim.play(); }); on(slideBackButton, "click", function(evt){ var anim = fx.slideTo({ node: slideTarget, left: "0", top: "100", beforeBegin: function(){ style.set(slideTarget, { left: "200px", top: "200px" }); } }); on(anim, "End", function(){ style.set(slideTarget, { backgroundColor: "red" }); }, true); anim.play(); }); }); </script>
你可能已经注意到了 beforeBegin 是以属性的方式配置的,原因是,你可以直接把事件写到动画的创建中,如果你在动画创建后再加入 beforeBegin 那就没有意义了。
链表传递
如果我有好几个动画要连续的一个个执行,那要怎么操作?你可以使用上面的 End 监听事件,当一个动画执行完成了再调用另一个动画。这当然可以,但这不是很方便。我们可以使用 dojo/fx 提供的链表传递来解决这个问题。直接看示例
<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> require(["dojo/_base/fx", "dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, fx, on, dom) { var slideAwayButton = dom.byId("slideAwayButton"), slideBackButton = dom.byId("slideBackButton"), slideTarget = dom.byId("slideTarget"); // Set up a couple of click handlers to run our chained animations on(slideAwayButton, "click", function(evt){ fx.chain([ baseFx.fadeIn({ node: slideTarget }), fx.slideTo({ node: slideTarget, left: "200", top: "200" }), baseFx.fadeOut({ node: slideTarget }) ]).play(); }); on(slideBackButton, "click", function(evt){ fx.chain([ baseFx.fadeIn({ node: slideTarget }), fx.slideTo({ node: slideTarget, left: "0", top: "100" }), baseFx.fadeOut({ node: slideTarget }) ]).play(); }); }); </script>
就如你所看到的,你在 fx.chain 中创建了多个动画,这些个动画将在chain的play触发时会被一个一个的执行
混合动画
还有一种 dojo/fx 提供的一种方法,是 combine 方法。这个方法将会在同一时间同时执行多个动画。在执行时间最长的那个动画完成后将会触发 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> require(["dojo/_base/fx", "dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, fx, on, dom) { var slideAwayButton = dom.byId("slideAwayButton"), slideBackButton = dom.byId("slideBackButton"), slideTarget = dom.byId("slideTarget"); // Set up a couple of click handlers to run our combined animations on(slideAwayButton, "click", function(evt){ fx.combine([ baseFx.fadeIn({ node: slideTarget }), fx.slideTo({ node: slideTarget, left: "200", top: "200" }) ]).play(); }); on(slideBackButton, "click", function(evt){ fx.combine([ fx.slideTo({ node: slideTarget, left: "0", top: "100" }), baseFx.fadeOut({ node: slideTarget }) ]).play(); }); }); </script>
在这个示例里,几个动画是同时执行的,是同时渐变和移动,不是先再渐变移动。通过混合动画你可以做出非常复杂和完成的效果。
结论
使用dojo的dojo/_base/fx和dojo/fx动画效果可以使你的页面非常的绚,你可以很轻松的创建一些简单的动画,也可以使用多种动画结合做出非常复杂的动画效果。
但是如果你想要做很精细和复杂的效果,你还要去了解dojo.animateProperty