上圖的 demo 主要講的 是 css transition的過渡回調函數transitionend事件;javascript
css3 的時代,css3--動畫 一切皆有可能;css
傳統的js 能夠經過回調函數判斷動畫是否結束;即便是採用CSS技術生成動畫效果,JavaScript仍然能捕獲動畫或變換的結束事件;html
transitionend
事件和animationend
事件標準的瀏覽器事件,但在WebKit瀏覽器裏你仍然須要使用webkit
前綴,因此,咱們不得不根據各類瀏覽器分別檢測事件java
1
2
3
4
5
6
|
var
transitions = {
'transition'
:
'transitionend'
,
'OTransition'
:
'oTransitionEnd'
,
'MozTransition'
:
'transitionend'
,
'WebkitTransition'
:
'webkitTransitionEnd'
}
|
下面附上源代碼:css3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
<!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><br><br>
//兼容性 詳情
|
另外,注意一下:在js調用中;transitionend 存幾個個問題:web
若是 transition 中:變換的屬性有多個 ;好比設置寬高 過分(transition :width:.2s,height:.2s), transitionend 事件會促發2次json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<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沒過渡 ;瀏覽器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<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動畫
1 通常是這樣解決 加個計時器延遲
2 或者 強制 /強制 獲取當前的內聯樣式
3或者重繪
都是從none到block ,dom元素剛生成未能即便渲染,致使過分失效,因此主動觸發頁面迴流(重繪),刷新DOM;
更改 offsetTop、offsetLeft、 offsetWidth、offsetHeight;scrollTop、scrollLeft、scrollWidth、scrollHeight;clientTop、clientLeft、clientWidth、clientHeight;getComputedStyle() 、currentStyle()。這些都會觸發迴流。迴流致使DOM從新渲染,平時要儘量避免,但這裏,爲了動畫即時生效播放,則主動觸發迴流,刷新DOM。
4 另外 部分低端安卓機型或者wp手機 沒法促發 transitionend事件 須要主動觸發一次
以上綜合解決方式大體以下;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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);
|
咱們進行封裝一下;封裝後的直接調用以下;參考zepto 改寫;不依賴任何類庫,詳情源碼調用例子 點擊transform.js 查看;該函數兼容性與zepto一致;
transform(dom元素,{ css屬性:css值},transitionDuration(單位:毫秒),transitionTiming,transitionend回調函數,transitionDelay(單位:毫秒));
transform(dom元素,keyframesName,animationDuration,animationTiming,animationend回調函數,animationDelay(單位:毫秒));
參數說明:
/* * 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) ; */
不要搞混css3動畫事件 webkitAnimationEnd 事件
至於animation關鍵幀動畫結束,提供了3個api;以下
開始事件 webkitAnimationStart
結束事件 webkitAnimationEnd
重複運動事件 webkitAnimationIteration;
1
|
本文地址:<a href=
"http://www.cnblogs.com/surfaces/"
target=
"_blank"
>http://www.cnblogs.com/surfaces/</a>
|
總結:
相同點:
二者都在移動端大放光彩;利用GPU加速性能,相對流暢;
利用 js進行對動畫結束事件能夠捕捉監聽;
區別之處
transition 只有惟一的事件 transitionend,而animation 有3個;
transition 強調過渡,Transition + Transform = 兩個關鍵幀的Animation
animation 強調流程與控制,Duration + TransformLib + Control = 多個關鍵幀的Animation
animation 能夠實時捕捉操做修改屬性, 而transition沒法捕捉 中間過程;
transition 每每須要事件驅動,hover,click之類 促發,animation從flash延伸出來