中断与停止CSS transition

可能本来就是这样,处于阶段的CSS3就不该大规模应用,浏览器商只是用它炫耀CSS能做行为层的事儿。现在人们比对待IE的CSS滤镜宽容多了,因此这事情还是逐一被其他浏览器所接受。在CSS3提供的两上实现动画的方案中,transition与animation,animation在DOM中没有对应的API,而transition则在我们动画暂停时遇上滑铁卢了——在webkit与opera中,我们是无法用removeProperty去掉transition的效果,一经定义就永远持续下去。在firefox中,我们还可以用覆写的方式去掉它们。

在开始演示之前,我给出取得CSS3 WebKitTransitionEvent事件名的方法:

var  getTransitionEndEventName = function (){
     var  obj = {
         'WebKitTransitionEvent' : 'webkitTransitionEnd' ,
         'TransitionEvent' : 'transitionend' ,
         'OTransitionEvent' : 'oTransitionEnd'
     }, ret ,e;
     for  ( var  name in  obj) {
         try  {
             document.createEvent(name);
             ret =  obj[name];
             console.log(ret)
          
         } catch  (ex) { }
     }
 
     getTransitionEndEventName = function (){
         return  ret
     }
     return  ret;
}
getTransitionEndEventName();

由于无法在webkit与opera上清除transition,这事件就可能无数次触发,这可不是我们愿意看到的。因此我们每次在中断或停止动画必须就元素解除绑定。

好了,下面进入正题。

方案一:使用一个新节点做替身。我们可以用cloneNode(true)弄一个一模一样的节点插入到原节点的前面,然后隐藏原来,将transition设置在新节点上,当动画中断或停止时,把当前的样式覆盖到原节点上,让它显示出来,再移除新节点!


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>dom Framework</title>
    <script>
      var dom = function(s){
        return document.getElementById(s)
      }


      dom.cssName = function (name){
        var prefixes = ['', '-ms-','-moz-', '-webkit-', '-khtml-', '-o-'],
        rcap = /-([a-z])/g,capfn = function($0,$1){
          return $1.toUpperCase();
        };
        dom.cssName = function(name, target, test){
          target = target || document.documentElement.style;
          for (var i=0, l=prefixes.length; i < l; i++) {
            test = (prefixes[i] + name).replace(rcap,capfn);
            if(test in target){
              return test;
            }
          }
          return null;
        }
        return dom.cssName(name);
      }
      window.onload = function(){
        var el = dom("test"),
        css3transition = dom.cssName("transition");
        var  animate = el.cloneNode(true);
        animate.innerHTML = "新节点"
        el.parentNode.insertBefore(animate,el);
        el.style.display = "none";
        animate.style[css3transition] = "all 1.5s ease-in"
      
        setTimeout(function(){
          animate.style.width = "400px";
        },0)
        setTimeout(function(){
          animate.style.width = "100px";
          animate.addEventListener("transitionend",function(){
            el.style.width = "100px"
            el.style.display = ""
            el.parentNode.removeChild(animate)
          },true)
        
        },1000)  ;
        //  setTimeout(function(){
        //   el.style.width = "300px";
        // },5000)  
      }
    </script>
    <style>
      #test{
        background: red;
        width:10px;
        height:30px;
      }
      #parent{
        width:410px;
        height: 32px;
        border: 1px solid blue;
      }
    </style>
  </head>
  <body>
    <h3>CSS3 动画 by 司徒正美</h3>
    <div id="parent">
      <div id="test">
        TEXT
      </div>
    </div>


    <button id="start" type="button">开始测试</button>
  </body>
</html>
    



但人们想在动画中进行对它进行操作呢?因为节点已不是原来的节点,因此维护成本非常高!

方案2:无视transition的永久效果。因为在中断或停止时,我们把当前样式取出来再覆盖上去,也可以中止动画。

<!DOCTYPE html>
<html>



  <head>
    <meta charset="utf-8">
    <title>dom Framework</title>
    <script>
      var dom = function(s){
        return document.getElementById(s)
      }


      dom.cssName = function (name){
        var prefixes = ['', '-ms-','-moz-', '-webkit-', '-khtml-', '-o-'],
        rcap = /-([a-z])/g,capfn = function($0,$1){
          return $1.toUpperCase();
        };
        dom.cssName = function(name, target, test){
          target = target || document.documentElement.style;
          for (var i=0, l=prefixes.length; i < l; i++) {
            test = (prefixes[i] + name).replace(rcap,capfn);
            if(test in target){
              return test;
            }
          }
          return null;
        }
        return dom.cssName(name);
      }
      window.onload = function(){
        var el = dom("test"),start,
        css3transition = dom.cssName("transition");
     
        el.style[css3transition] = "all 5000ms ease-in"
        
        dom("pause").onclick = function(){
          var computedStyle = document.defaultView.getComputedStyle( el, null );
          el.style.width = computedStyle.getPropertyValue( "width" );
          var elapsed = new Date - start;
          var old = el.style[css3transition]
          el.style[css3transition] = old.replace(/\d+ms/g,function(a){
            return (parseFloat(a) - elapsed) +"ms"
          })
         //  el.style[css3transition] = "all 5000ms ease-in"
        }
        dom("resume").onclick = function(){
          el.style.width = "400px";
        }
        setTimeout(function(){
          start = new Date;
          el.style.width = "400px";
        },0);
  
        
      }
    </script>
    <style>
      #test{
        background: red;
        width:10px;
        height:30px;
      }
      #parent{
        width:400px;
        height: 31px;
        border: 1px solid blue;
      }
    </style>
  </head>
  <body>
    <h3>CSS3 动画 by 司徒正美</h3>
    <div id="parent">
      <div id="test">
        TEXT
      </div>
    </div>
    <button id="pause" type="button">中断</button>
    <button id="resume" type="button">继续</button>
  </body>
</html>




但无视终归是逃避问题,不清除transition,以后每次对元素的CSS操作都会动画化(除了在FF中),因此也不可行。

综上所述,CSS3对行为层的干涉至今还是不成熟的。作为一个成熟的框架不应该把它作为构建动画的手段。

原文地址: http://www.cnblogs.com/rubylouvre/archive/2011/09/11/2172539.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值