zoukankan      html  css  js  c++  java
  • 第四十课:CSS3 transition详解

    W3C中对transition是这样描述的:允许css的属性值在一定的时间内平滑的过渡,也就是说,以动画的效果改变css的属性值。

    transition主要包含4个属性值:transition-property:样式名;transition-duration:持续时间;transition-timing-function:缓动公式;transition-delay:延迟多长时间才触发。接下来我们来详细讲下这四个属性值。

    transition-property

    transition-property是用来指定当元素的哪个属性值变化时,就执行transition效果的。主要有以下几个值:none(没有属性会获得过渡效果,也就是说设置了none,此元素不会有过渡效果,就跟没设置transition一样);all(只要元素的任何一个属性改变,就会有过渡效果,这是默认值);property(具体的属性名,可以有多个,用逗号分开,比如:transition-property: width,height;);

    transition-duration

    动画持续的时间,单位可以是s,也可以是ms。我们可以多个持续时间值,比如:transition-duration:1s, 1500ms, 2s;transition-property:width,height,color。其中1s对应width属性改变,1500ms对应height属性的改变,2s对应color属性的改变。默认值为0.

    transition-timing-function

    缓动公式,根据时间的推进,去改变属性值的变换速度。它主要有6个值:

    ease(逐渐变慢),默认值

    linear(匀速)

    ease-in(加速)

    ease-out(减速),跟ease的区别是,减速的变化程度不一样。

    ease-in-out(先加速,再减速)

    cubic-bezier,允许你自定义一个时间曲线,通过cubic-bezier(x1,y1,x2,y2),此属性值可以模拟以上5个状态,只要传入相应的x1,y1,x2,y2给cubic-bezier(x1,y1,x2,y2)。这4个值必须在[0,1]之间,否则无效。

    transition-delay

    延迟多长时间,才进行变化,单位有s,ms。默认值为0.

    举个例子来展示下transition如何使用:

    <style>

      #move{

        position:absolute;

        left:0px;

        100px;

        height:100px;

        background:red;

        font-size:14px;

      }

      #move:hover{      //鼠标移动到move元素时,就会动态的改变它的三个属性值background,font-size,left。

        background:green;

        font-size:26px;

        left:700px;

        transition: all 2s ease 0.3s;

        -moz-transition: all 2s ease 0.3s;

        -webkit-transition: all 2s ease 0.3s;

        -o-transition: all 2s ease 0.3s;     

      }

    </style>

    著名的Bootstrap的动画就是基于transition的。另外,当上面的这个动画(过渡效果)结束后,就会触发一个transitionEnd的事件。此transitionEnd在不同浏览器下具有不同的写法,比如:webkitTransitionEnd,oTransitionEnd等。那么,我们如何来取得这个可用的事件名呢?

    第一种方法:动态创建一个元素与一个样式表插入DOM树中,然后改变目标样式值,从而触发回调,得到事件的名字,最后把元素和样式表从DOM树中删除。

    (function(){

      var span = document.createElement("span");   //创建一个元素span

      span.id = "chaojidan";

      span.innerHTML = "test";

      var body = document.body || document.documentElement;

      var style = document.createElement("style");   //创建一个元素style

      body.appendChild(span);

      body.appendChild(style);   //添加到页面中

      style.innerHTML = "#chaojidan{color:red;opacity:0;height:1px;overflow:hidden;-moz-transition:color 0.1s;-webkit-transition:color 0.1s;-o-transition:color 0.1s;}";     //设置元素span的样式,只要改变span的color属性值,就会触发过渡动画。

      "transitionend otransitionend oTransitionEnd webkitTransitionEnd".replace(/w+/g,function(type){    //type就是每次正则匹配的值

        span.addEventListener(type,function(e){   //给元素span绑定过渡动画结束后的触发的事件,这里绑定了4个。

          window.transitionEnd = e.type;     //浏览器支持哪个名字,就会执行到这里,然后把事件的类型,赋给window对象的transitionEnd。

        },false);

      });

      setTimeout(function(){span.style.color="black";});   //执行span元素的过渡动画,用时100ms。

      setTimeout(function(){

        body.removeChild(span);

        body.removeChild(style);

      },1000); 

    })();

    第二种方法:从事件的构造器着手,如果把事件构造器的名字直接传入到createEvent,不抛错,就证明浏览器支持这种事件。

    var getTransitionEnd = function(){

      var obj = {

        "TransitionEvent":"transitionend",

        "WebKitTransitionEvent":"webkitTransitionEnd",

        "OTransitionEvent":"oTransitionEnd",

        "otransitionEvent":"otransitionEnd"

      };

      var ret;

      for(var name in obj){

        try{

          var a = document.createEvent(name);

          ret = obj[name];

          break;

        }catch(){}

      }

      getTransitionEnd  = function(){   //重写此方法,只需要检测一次,下次直接返回缓存结果,这叫做惰性函数。

        return ret;

      }

      return ret;

    }

    最后,我们用css transition实现一个动画效果:

    <style>

      #test{

        100px;height:100px;position:absolute;background:red;

        left:0;  

          transition: left 5s;

        -moz-transition: left 5s;

        -webkit-transition: left 5s;

        -o-transition: left 5s;     

      }

    </style>

    <script>

      var $ = function(id){

        return document.getElementById(id);

      }

      var el = $("test");

      $("run").onclick = function(){    //点击run按钮时,触发过渡动画效果,此动画把元素test从0移动到700,用时5s。

        el.style.left = "700px";

      }

      $("stop").onclick = function(){  //点击stop按钮,将会停止过渡动画。

        var left = window.getComputedStyle(el,null).left;   //得到元素test的当前left的值

        el.style.left = left;   //当test元素在运动时,你点击了stop按钮的话,test元素会马上停止。

        ["", "-moz-", "-o-", "-webkit-"].forEach(function(prefix){

          el.style.removeProperty(prefix +"transition");   //DOM2定义的style方法,低版本IE浏览器不支持。这里只能删除标签上的style样式值

        });

      }

    </script>

    上面的例子暴露出transition的弱点了,虽然我们停止动画时,可以通过取当前的left值然后重新赋值的手段实现了,但是只要transition这个样式没有没清除掉,那么,我们后面每一次变动left这个样式值,都会发生过渡动画效果。而想移除这个transition样式,只有当它写在标签的style属性中时,我们才能很好的删除。如果它是定义在内部样式(我们例子中写法)或外部样式,那么要删除就比较麻烦了(可以通过CSSStyleSheet对象删除)。但是如果外部样式是跨域获取的,那么删除样式规则这个手段就失效了,意思就是无法删除transition样式值了。

    因此,使用transition实现动画效果,可控性太差,不适合作为一个框架的动画引擎的实现手段。

    加油!

  • 相关阅读:
    Yahoo团队经验:网站性能优化的34条黄金法则
    SaltStack中状态间关系unless、onlyif、require、require_in、watch、watch_in
    kubectl 常用命令一
    Linux系统的限制
    DNS服务器搭建与配置
    Python对文件的操作
    SaltStack schedule功能
    saltstack的salt-api介绍
    SaltStack事件驱动 – event reactor
    SaltSack 中Job管理
  • 原文地址:https://www.cnblogs.com/chaojidan/p/4211584.html
Copyright © 2011-2022 走看看