相信大家在試用css3動畫時候一定用過transition屬性,相對於js動畫來說用起來更快速簡單。
程式碼如下:
HTML結構:
1 2 |
<div id="box"></div> <button>動畫按鈕</button> |
CSS程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.box { background: goldenrod; width: 300px; height: 300px; margin: 30px auto; transition: all .4s linear; /*display: block;*/ } .hidden { /*display: none;*/ opacity: 0; } |
JS程式碼
1 2 3 4 5 6 7 8 |
var box = $('#box'); $('button').on('click', function () { if(box.hasClass('hidden')){ box.removeClass('hidden'); }else{ box.addClass('hidden'); } }); |
在點選按鈕後可以看到淡入淡出的動畫效果,但是在css程式碼中解除對於display屬性的兩段註釋以後,再開啟瀏覽器一看,淡入淡出的效果全沒了。
這簡直是破壞性的作用,然後我度娘了一下總結了幾個方法。
第一種方法:將display用visibility來替代,大家都知道visibility的效果其實跟display在一定程度上相似,那為什麼說只是一定程度上相似呢,因為它仍然是佔空間的,那你一定會說,這麼用跟opacity沒啥區別呀。但卻可以避免遮擋下面的層比如按鈕的點選事件。
第二種方法是相對於第一種方法的進階,利用了js的setTimout和transitionend事件
css程式碼 將class hidden類中的opacity分離出來
CSS程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.box { background: goldenrod; width: 300px; height: 300px; margin: 30px auto; transition: all .4s linear; visibility: visible; } .hidden { display: none; } .visuallyhidden { opacity: 0; } |
js程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var box = $('#box'); $('button').on('click', function () { if (box.hasClass('hidden')) { box.removeClass('hidden'); setTimeout(function () { box.removeClass('visuallyhidden'); }, 20); } else { box.addClass('visuallyhidden'); box.one('transitionend', function(e) { box.addClass('hidden'); }); } }); |
第三種方法與第二種方法類似,用requestAnimationFrame來取代setTimeout,相應的修改了if條件裡的js。
requestAnimationFrame其實也就跟setTimeout/setInterval差不多,通過遞迴呼叫同一方法來不斷更新畫面以達到動起來的效果,但它優於setTimeout/setInterval的地方在於它是由瀏覽器專門為動畫提供的API,在執行時瀏覽器會自動優化方法的呼叫,並且如果頁面不是啟用狀態下的話,動畫會自動暫停,有效節省了CPU開銷。
js程式碼如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var box = $('#box'); $('button').on('click', function () { if (box.hasClass('hidden')) { box.removeClass('hidden'); requestAnimationFrame(function(){ box.removeClass('visuallyhidden'); }); } else { box.addClass('visuallyhidden'); box.one('transitionend', function(e) { box.addClass('hidden'); }); } }); |
以上就是當transition遇上display時碰到的坑。