Dojo 网页特效基础<12>

在这个教程中,我们将讲解Dojo 中的特效使用, 它将使你的网页或应用更加有趣。

开始

到目前为止,我们已经很容易操作DOM 以及处理DOM节点的事件。 可是, 我们在做这些动作时(删除,添加节点等), 过渡时会很生硬: 删除一个节点使它从一个页面中消失, 突然的消失会让浏览者感到迷惑。 使用 DOjo提供的标准特效, 我们可以流畅的用户体验。 更进一步, 如果我们在采用dojo/_base/fx 和dojo/fx模块, 我们链接和混全这些效果,创造更加眼花缭乱,动态的用户体验。

!* Dojo 1.9 有两个 fx 模块: dojo/_base/fx 和dojo/fx
  • dojo/_base/fx 提供基本的特效方法,它也是之前Dojo基础里一部分。 包括, animateProperty,anim,fadeIn 和 fadeOut.
  • dojo/fx 提供更高级的特效,包括: chain,combine,wipeIn wipeOut 和 slideTo

渐入/渐出

有一个动画你可能已经在应用程序里见过,那就是使一个节点渐入或者渐出。 这个效果非常普通也很简单, 它是 dojo/_base/fx核心效果的一部分。 我们可以使用它来在网页中隐藏和显示一个元素,感觉起来会更流畅。下面是一个例子:
<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,function(evt){
            fx.fadeIn({ node: fadeTarget }).play();
        });
    });
</script>

所有的动画函数都接受一个参数: 一个对象的属性。 node 属性是最重要的: 一个DOM节点或者 一个节点的字符串ID. 别一个属性是 duration,动画持续的时间,单位为毫秒。 duration默认的时间为350毫秒。 这里还有其它的一些动画属性, 但 渐入和渐出不需要使用到。

动画函数返回一个 dojo/_base/fx::Animation 对象,它提供了多种方法: play,pause,stop,status 和 gotoPrecent. 动画在它们创建是还没有开始播放, 必须手动的通过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",dom) {
        var wipeOutButton = dom.byId("wipeOutButton"),wipeInButton = dom.byId("wipeInButton"),wipeTarget = dom.byId("wipeTarget");
 
        on(wipeOutButton,function(evt){
            fx.wipeOut({ node: wipeTarget }).play();
        });
        on(wipeInButton,function(evt){
            fx.wipeIn({ node: wipeTarget }).play();
        });
    });
</script>

擦除效果在 dojo/fx模块。 在这个例子中,我们给目标节点添加了一个 wipe 的css类。 因为wipe 的函数操作的是节点的内容高度,而不是一个确切的高度值。 "wipe"类设置目标节点的高度为"auto".


滑动效果

目前为此我们讲解了隐藏节点, 但如果我们想移动它们到某点该做什么呢? 渐入和渐隐或者擦除 都不能改变节点的位置。
<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",dom) {
        var slideAwayButton = dom.byId("slideAwayButton"),slideBackButton = dom.byId("slideBackButton"),slideTarget = dom.byId("slideTarget");
 
        on(slideAwayButton,function(evt){
            fx.slideTo({ node: slideTarget,left: "200",top: "200" }).play();
        });
        on(slideBackButton,left: "0",top: "100" }).play();
        });
    });
</script>

查看 Demo

动画事件

如之前讨论的, 所有的动画方法会返回一个 dojo/_base/fx::Animation 对象。 这些对象不仅仅提供 play或者pause来控制动画。 也提供一系列可被我们监听的事件, 事件为我们提供了在动画开始, 执续,完成之后,可以做些其它的动作。 两个非常重要也很常用的事件监听是 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/dom-style",style,dom) {
 
        var slideAwayButton = dom.byId("slideAwayButton"),slideTarget = dom.byId("slideTarget");
 
            on(slideAwayButton,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,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,function(evt){
                var anim = fx.slideTo({
                    node: slideTarget,top: "100",beforeBegin: function(){
 
                        style.set(slideTarget,{
                            left: "200px",top: "200px"
                        });
                    }
                });
 
                on(anim,{
                        backgroundColor: "red"
                    });
                },true);
 
                anim.play();
            });
    });
</script>

你可能已经注意到 beforeBegin作为一个属性传递给参数对象。 原因在于确保动画在创建时连接上 beforeBegin。 因此,如果你在创建完动画之后在 注册 beforeBegin事件, 你的事件处理器会在动画的beforeBegin处理器之后处理(不能用on(anim,"beforeBegin",function(){}),没有暴露beforeBegin,只爆露出 "Begin",但 "Begin"是动画开始时,而不是开始前。 将监听器作为对象的属性, 你可以保证你的监听器最先执行。


动作链(连续的动画)

如果我们想依次触发动画该做什么? 我们可以在End事件的处理函数里设置下一步效果, 但这样不是很方便。 dojo/fx模块给我们提供了更方便的一些方法来设置动画依次执行或并列执行。而每个方法返回一个新的dojo/_base/fx::Animation对象, 每个对象都自己拥有一套代表整套(多个事件)的事件和方法。 让我们先看看 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>
    require(["dojo/_base/fx","dojo/fx",function(baseFx,fx,slideTarget = dom.byId("slideTarget");
 
        // Set up a couple of click handlers to run our chained animations
        on(slideAwayButton,function(evt){
            fx.chain([
                baseFx.fadeIn({ node: slideTarget }),fx.slideTo({ node: slideTarget,top: "200" }),baseFx.fadeOut({ node: slideTarget })
            ]).play();
        });
        on(slideBackButton,top: "100" }),baseFx.fadeOut({ node: slideTarget })
            ]).play();
        });
 
    });
</script>

如你看到的, 我们创建了直接在fx.chain里创建了一些效果, 当返回了dojo/_base/fx::Animation 时立即调用 play方法开始整个动画。 我们不能在动画链里开始单独的动画,但利用fx.chain的事件处理器可以。

组合动画

dojo/fx提供的第二个方法是combine. combine将使多个动画在同一时间运行。 dojo/_base/fx::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>
    require(["dojo/_base/fx",slideTarget = dom.byId("slideTarget");
 
        // Set up a couple of click handlers to run our combined animations
        on(slideAwayButton,function(evt){
            fx.combine([
                baseFx.fadeIn({ node: slideTarget }),top: "200" })
            ]).play();
        });
        on(slideBackButton,function(evt){
            fx.combine([
                fx.slideTo({ node: slideTarget,baseFx.fadeOut({ node: slideTarget })
            ]).play();
        });
 
    });
</script>

假若这样, fade 和 slideTo不在是依次运行,还是同时运行。

使用fx.chian 和 fx.combine,你可以建立一些非常复杂的动画序列。 也因为 chain 和 combine 都会返回一个 animation对象, 这样chain 和 combine方法返回的结果又可以被链接或组合。 允许你从简单的动画,在到复杂的动画。


总结

使用Dojo,非常简单的就能给你的网页添加效果。 通过dojo/_base/fx和 dojo/fx模块,你可以对DOM节点渐入和渐出, 也可以简单的移动和擦除你的节点。 通过 链接和组合动画可以创建更加高级的动画。

可是, 如果你想做更多高级的事件时, 比如调整一个DOM节的高度,而未必将高度一直委缩到 0. 或许还会通过动画来调整一个背景颜色. 还有更多的动画属性,查看 fx.animationProperty,更详细的内容会在下一教程中讲解。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我有一个网格,可以根据更大的树结构编辑小块数据.为了更容易知道用户保存了什么,我希望当用户第一次看到网格时,网格处于不可编辑状态.当用户准备好后,他们可以单击编辑按钮,这将使网格的某些部分可编辑.然后,有一个保存或取消按钮可以保存更改或还原.在大多数情况下它是有效的.但
我即将开始开发一款教育性的视频游戏.我已经决定以一种我可以轻松打包为Web,Mobiles和可能的Standalone版本的方式来实现这一目标.我不想使用Flash.因此,我确信(无论如何我会听取建议)使用JavaScript和SVG.我正在对这个问题进行大量研究,但我很难把各个部分放在一起.我知道Raphae
我正在使用带有Grails2.3.9的Dojo1.9.DojoNumberTextBox小部件–我在表单中使用–将固定格式(JavaScript基本格式)的实数值(例如:12.56)设置为HTML表单输入字段(但根据浏览器区域设置显示/编辑它们,所以用户总是看到格式正确的数字).另一方面,Grails期望输入字段根据浏览器
1.引言鉴于个人需求的转变,本系列将记录自学arcgisapiforjavaScript的学习历程,本篇将从最开始的arcgisapiforjavaScript部署开始,个人声明:博文不在传道受业解惑,旨在方便日后复习查阅。由于是自学,文章中可能会出现一些纰漏,请留言指出,不必留有情面哦!2.下载ArcGISforDe
我正在阅读使用dojo’sdeclare进行类创建的语法.描述令人困惑:Thedeclarefunctionisdefinedinthedojo/_base/declaremodule.declareacceptsthreearguments:className,superClass,andproperties.ClassNameTheclassNameargumentrepresentsthenameofthec
我的团队由更多的java人员和JavaScript经验丰富组成.我知道这个问题曾多次被问到,但为了弄清楚我的事实,我需要澄清一些事情,因为我在客户端技术方面的经验非常有限.我们决定使用GWT而不是纯JavaScript框架构建我们的解决方案(假设有更多的Java经验).这些是支持我的决定的事实.>
路由dojo/framework/srcouting/README.mdcommitb682b06ace25eea86d190e56dd81042565b35ed1Dojo应用程序的路由路由FeaturesRoute配置路径参数RouterHistoryManagersHashHistoryStateHistoryMemoryHistoryOutletEventRouterContextInjectionOutl
请原谅我的无知,因为我对jquery并不熟悉.是否有dojo.connect()的等价物?我找到了这个解决方案:http:/hink-robot.com/2009/06/hitch-object-oriented-event-handlers-with-jquery/但是没有断开功能!你知道jquery的其他解决方案吗?有jquery.connect但这个插件在我的测试中不起作用.
与java类一样,在dojo里也可以定义constructor 构造函数,在创建一个实例时可以对需要的属性进行初始化。//定义一个类mqsy_yjvar mqsy_yj=declare(null,{     //thedefaultusername    username: "yanjun",          //theconstructor   
我一直在寻找一些最佳实践,并想知道Dojo是否具有框架特定的最佳实践,还是最好只使用通用的Javascript标准?特别是我主要是寻找一些功能和类评论的指导方针?解决方法:对于初学者来说,这是项目的风格指南:DojoStyleGuide
我有’05/17/2010’的价值我想通过使用dojo.date.locale将其作为“2010年5月17日”.我尝试过使用dojo.date.locale.parse,如下所示:x='05/17/2010'varx=dojo.date.locale.parse(x,{datePattern:"MM/dd/yyyy",selector:"date"});alert(x)这并没有给我所需的日期
我正在尝试创建一个包含函数的dojo类,这些函数又调用此类中的其他函数,如下所示:dojo.provide("my.drawing");dojo.declare("my.drawing",null,{constructor:function(/*Object*/args){dojo.safeMixin(this,args);this.container=args[0];
我知道你可以使用jQuery.noConflict为jQuery做这件事.有没有办法与Dojo做类似的事情?解决方法:我相信你可以.有关在页面上运行多个版本的Dojo,请参阅thispage.它很繁琐,但似乎是你正在寻找的东西.一般来说,Dojo和jQuery都非常小心,不会破坏彼此或其他任何人的变量名.
我有一个EnhancedGrid,用户经常使用复杂的过滤器.有没有办法允许用户保存或标记过滤器,以便将来可以轻松地重新应用它?我知道我可以通过编程方式设置过滤器,但我无法预测用户想要的过滤器.谢谢!编辑:自己做了一些进展…使用grid.getFilter()返回过滤器的JSON表示,然后使用json.strin
我有这个代码:dojo.declare("City",null,{constructor:function(cityid,cityinfo){}});dojo.declare("TPolyline",GPolyline,{constructor:function(points,color){},initialize:function(map){});应该是什
我遇到的问题是我的所有javascript错误似乎来自dojo.xd.js或子模块.我正在使用chrome调试器和许多dijit功能,如dijit.declaration和dojo.parser.这有点烦人,因为它很难找到简单的错误或滑倒.我希望我可以添加一个选项,允许我的调试器在我的非dojo代码中显示选项会发生的位置.我是
我正在使用DojoToolkit数字/解析函数来处理格式化和使用ICU模式语法解析字符串.有没有人知道有可能采取任意ICU模式字符串并以某种方式使用Dojo(或其他)库将其分解为它的部分(例如,对于数字模式,它可以被分解为小数位数,数千个分组等…).我希望这样做,而不需要让我的代码密切了
我有两个看似相关的问题,访问在不同的地方定义的javascript函数.我遇到的第一个问题是调用我在firgbug或safari控制台中定义的函数.我定义了一个名为getRed的函数,如下所示:functiongetRed(row,col){//dosomethingstuffandreturntheredvalueasa
我想添加一个在Ajax调用中指定的外部样式表.我已经找到了一种方法来使用jQuery(参见下面的示例),但是我需要使该方法适应dojoJavaScript框架.JQuery示例$('head').append('<linkrel="stylesheet"type="text/css"href="lightbox_stylesheet.css">');谢谢.解决方法:一旦你
我正在尝试使用dojo.connect将onMouseDown事件连接到图像,如:dojo.connect(dojo.byId("workpic"),"onMouseDown",workpicDown);functionworkpicDown(){alert("mousedown");}类似的代码几行后,我将onMouse*事件连接到dojo.body确实完全正常工作.但是当我点击图像时