上圖的 demo 主要講的 是 css transition的過渡回調函數transitionend事件;javascript
css3 的時代,css3--動畫 一切皆有可能;css
傳統的js 能夠經過回調函數判斷動畫是否結束;即便是採用CSS技術生成動畫效果,JavaScript仍然能捕獲動畫或變換的結束事件;html
transitionend
事件和animationend
事件標準的瀏覽器事件,但在WebKit瀏覽器裏你仍然須要使用webkit
前綴,因此,咱們不得不根據各類瀏覽器分別檢測事件java
var transitions = { 'transition':'transitionend', 'OTransition':'oTransitionEnd', 'MozTransition':'transitionend', 'WebkitTransition':'webkitTransitionEnd' }
下面附上源代碼:css3
<!doctype html> <html> <head> <meta charset="utf-8"> <title>suface js判斷css動畫是否結束</title> </head> <body> <p>一旦動畫或變換結束,回調函數就會觸發。再也不須要大型類庫支持。<br> </p> <style type="text/css"> .sample { width: 200px; height: 200px; border: 1px solid green; background: lightgreen; opacity: 1; margin-bottom: 20px; transition-property: opacity; /*transition-duration: .5s;*/ transition-duration:3s; } .sample.hide { opacity: 0; } </style> <div class="sample">css3動畫過分慢慢隱藏(transition-duration:3s;)</div> <p><button onclick="this.style.display='none';startFade();">慢慢消退,檢測結束事件</button></p> <script> ;(function() { var e = document.getElementsByClassName('sample')[0]; function whichTransitionEvent(){ var t, el = document.createElement('surface'), transitions = { 'transition':'transitionend', 'OTransition':'oTransitionEnd', 'MozTransition':'transitionend', 'WebkitTransition':'webkitTransitionEnd' } for(t in transitions){ if( el.style[t] !== undefined ){ return transitions[t]; } } } var transitionEvent = whichTransitionEvent(); transitionEvent && e.addEventListener(transitionEvent, function() { alert('css3運動結束!我是回調函數,沒有使用第三方類庫!'); e. removeEventListener(transitionEvent,arguments.callee,false);//銷燬事件 }); startFade = function() { e.className+= ' hide'; } })(); </script> </body> </html>
//兼容性 詳情
另外,注意一下:在js調用中;transitionend 存幾個個問題:web
若是 transition 中:變換的屬性有多個 ;好比設置寬高 過分(transition :width:.2s,height:.2s), transitionend 事件會促發2次json
<style> .surfaces_box{ background:url(../../loveImg/QioA-fxehfqi8208393.jpg) no-repeat center center;;width:550px;;height:343px;; margin:0 auto; position: relative;} .surfaces_box p{ position:absolute; bottom:0; left:0; right:0; color:#333; text-align:center; padding:10px 0; background: rgba(255,255,255,.4) } .surfaces{width:100px;height:100px;background:red; color:#fff; text-align:center; transition:width 1s ,height 1s;} </style> <div class="surfaces_box"> <div class="surfaces" id="j_surfaces">click me </div> <p>http://www.cnblogs.com/surfaces/</p> </div> <script> function addEnd(obj,fn){ obj.addEventListener('WebkitTransitionEnd',fn,false); obj.addEventListener('transitionend',fn,false); } var surfaces=document.getElementById("j_surfaces"); surfaces.onclick=function(){ this.style.width=this.offsetWidth+100+"px"; this.style.height=this.offsetHeight+100+"px"; }; addEnd(surfaces,function(){ alert('CSS3 過渡結束回調 '); }); </script>
若是 transition 中:變換的屬性 (transition :width:.1s);transitionend 以後再次改變 寬度; 再次促發 transition相似遞歸;api
<style> .surfaces_box{ background:url(../../loveImg/QioA-fxehfqi8208393.jpg) no-repeat center center;;width:550px;;height:343px;; margin:0 auto; position: relative;} .surfaces_box p{ position:absolute; bottom:0; left:0; right:0; color:#333; text-align:center; padding:10px 0; background: rgba(255,255,255,.4) } .surfaces{width:100px;height:100px;background:red; color:#fff; text-align:center; transition:width 1s} </style> <div class="surfaces_box"> <div class="surfaces" id="j_surfaces">click me </div> <p>http://www.cnblogs.com/surfaces/</p> </div> <script> function addEnd(obj,fn){ obj.addEventListener('WebkitTransitionEnd',fn,false); obj.addEventListener('transitionend',fn,false); } var surfaces=document.getElementById("j_surfaces"); surfaces.onclick=function(){ this.style.width=this.offsetWidth+100+"px"; }; addEnd(surfaces,function(){ this.style.width=this.offsetWidth+100+"px"; alert('CSS3 過渡結束回調 '); }); </script>
若是元素原先display:none 到block,transition 過渡無效;可能致使transitionend 失效;舉個例子 dom元素從display:none 到block ,dom的opacity從0到1的 transition沒過渡 ;瀏覽器
<style> .surfaces_box{ background:url(../../loveImg/QioA-fxehfqi8208393.jpg) no-repeat center center;;width:550px;;height:343px;; margin:0 auto; position: relative;} .surfaces_box p{ position:absolute; bottom:0; left:0; right:0; color:#333; text-align:center; padding:10px 0; background: rgba(255,255,255,.4) } .surfaces{width:100px;height:100px;background:red; color:#fff; text-align:center; transition:width 1s} .surfaces_box .hideElement{width:100px;height:100px; position:absolute; right:0; top:0; background:red; color:#fff; text-align:center; transition:opacity 1s; display:none; opacity:0;} </style> <div class="surfaces_box"> <div class="surfaces" id="j_surfaces">click me </div> <div class="hideElement" id="j_hideElement">opacity transition</div> <p>http://www.cnblogs.com/surfaces/</p> </div> <script> var j_hideElement=document.getElementById("j_hideElement"); var surfaces=document.getElementById("j_surfaces"); surfaces.onclick=function(){ j_hideElement.style.display='block'; //// 原先display=none j_hideElement.style.opacity=1; // transition:opacity 1s; }; </script>
上圖 dom元素 從none到block,致使 transition-duration 沒法渲染; css3動畫
都是從none到block ,dom元素剛生成未能即便渲染,致使過分失效,因此主動觸發頁面迴流(重繪),刷新DOM;
更改 offsetTop、offsetLeft、 offsetWidth、offsetHeight;scrollTop、scrollLeft、scrollWidth、scrollHeight;clientTop、clientLeft、clientWidth、clientHeight;getComputedStyle() 、currentStyle()。這些都會觸發迴流。迴流致使DOM從新渲染,平時要儘量避免,但這裏,爲了動畫即時生效播放,則主動觸發迴流,刷新DOM。
var fired = false; var handler = function () {//回調函數中解綁事件 callback && callback.apply(obj,arguments); fired=true; obj.removeEventListener(transitionEnd,arguments.callee,false) }; if(obj.addEventListener){ obj.addEventListener(transitionEnd, handler,false); } setTimeout(function(){//綁定過事件還作延時處理,是transitionEnd在older Android phones不必定觸發 if(fired) return handler() },(duration + delay) + 25);
參數說明:
/* * js transfrom.js * @param obj {obj} 原生dom對象 * @param properties {json} ||string { translate3d:'220px,10px,0',left:'1em',opacity:0.2, rotateY:'30deg'} || animationName 多個能夠以逗號分割 如 'fadeIn,sliderDown'; * @param duration {number} 默認400毫秒 可省略 * @param ease {str} 默認linear,可省略 支持 cubic-bezier(0.42,0,1,1)寫法; * @param callback {function} 回調函數 可省略 * @param delay {number} 延遲時間 可省略 */
多種參數 調用寫法示例:
/* http://www.cnblogs.com/surfaces * @param properties 爲 {} 或者 string ;若是 properties= string 爲animation- name * transform(elem, properties) * transform(elem, properties, ease) * transform(elem, properties, ease, delay) * transform(elem, properties, ease, callback, delay) * transform(elem, properties, callback) * transform(elem, properties, callback, delay) * transform(elem, properties, duration ) * transform(elem, properties, duration, ease) * transform(elem, properties, duration, delay) * transform(elem, properties, duration, callback) * transform(elem, properties, duration, callback,delay) * transform(elem, properties, duration, ease, delay) * transform(elem, properties, duration, ease, callback) * transform(elem, properties, duration, ease, callback,delay) //使用示例以下: transform(elem,{translateX:'150px',left:'1em',opacity:0.2,perspective:'400px', rotateY:'40deg'},600,'linear', function(){ console.log('transition結束回調') },200) ; transform(elem, keyframesName,600,'linear',function(){ console.log('animation結束回調') },200) ; */
至於animation關鍵幀動畫結束,提供了3個api;以下
開始事件 webkitAnimationStart
結束事件 webkitAnimationEnd
重複運動事件 webkitAnimationIteration;
本文地址:http://www.cnblogs.com/surfaces/
相同點:
二者都在移動端大放光彩;利用GPU加速性能,相對流暢;
利用 js進行對動畫結束事件能夠捕捉監聽;
區別之處
transition 只有惟一的事件 transitionend,而animation 有3個;
transition 強調過渡,Transition + Transform = 兩個關鍵幀的Animation
animation 強調流程與控制,Duration + TransformLib + Control = 多個關鍵幀的Animation
animation 能夠實時捕捉操做修改屬性, 而transition沒法捕捉 中間過程;
transition 每每須要事件驅動,hover,click之類 促發,animation從flash延伸出來