如demo(若是沒有顯示,請查看源地址http://jsfiddle.net/ihardcoder/HNduT/2/)所示,基本的效果是在點擊「Translate」按鈕後,藍色區域透明度變爲0,而後隱藏display:none;點擊Reset按鈕後,首先顯示藍色區域display:block,而後透明度逐漸恢復至1,代碼以下:javascript
1 var btn1 = $("#testbtn1"); 2 var btn2 = $("#testbtn2"); 3 var container = $("#container"); 4 5 btn1.on('click', function(e) { 6 container.css({ 7 "transition": "opacity 1s", 8 "-webkit-transition": "opacity 1s", 9 "-moz-transition": "opacity 1s", 10 "-o-transition": "opacity 1s", 11 "-ms-transition": "opacity 1s", 12 "opacity": "0.1" 13 }); 14 setTimeout(function() { 15 container.css("display", "none"); 16 }, 1000); 17 }); 18 btn2.on('click', function(e) { 19 container.css("display","block"); 20 container.css("display"); 21 container.css("opacity","1"); 22 });
上述代碼中第20行看起來很奇怪,可能會有人疑問這句代碼的做用,事實是,若是沒有這句代碼,在點擊Reset後獲得的效果是:藍色區域瞬間顯示出來,並無透明度改變的過渡效果。css
至於產生這種現象的緣由,深層次的機制我也還沒有搞明白,暫時理解爲CSS3的transition過渡不支持display的改變,直接操做display會破壞transition的動畫,因此在第14行經過setTimeout將opacity的transition動畫與display的操做分隔。java
而第20行代碼的目的,我是這樣理解的,瀏覽器的UI線程在處理UI操做時,將多個css屬性的set操做加入在同一個tick中處理(關於瀏覽器處理tick機制,請參考http://www.infoq.com/cn/articles/javascript-high-performance-animation-and-page-rendering?utm_source=infoq&utm_medium=popular_links_homepage),也就是說,若是不插入第20行代碼,第19行和第21行的css屬性set操做將會被同時執行,因此將會獲得瞬間顯示出來的效果;第20行代碼實際上是css屬性的get操做,個人理解是,若是在兩個css屬性的set操做中間插入get操做,UI線程在處理的時候將會按順序執行,display的操做和opacity的操做在不一樣的tick中被執行,這樣便的到咱們想要的過渡效果。web
第二種方法,因爲display對transition的破壞做用,還有另一種方法來hack,沒有錯,就是setTimeout!(這貨徹底是js的大殺器!)代碼以下:chrome
1 btn2.on('click', function(e) { 2 container.css("display","block"); 3 setTimeout(function(){ 4 container.css("opacity","1"); 5 },delay); 6 });
可是用setTimeout的方法有一個弊端,第5行的delay在不一樣的瀏覽器(甚至不一樣版本的相同瀏覽器)中須要設置不一樣的數值,經本人測試,chrome35和IE10下delay=0便可,Firefox30下delay>=14.瀏覽器
第三種解決方法是經過window.requestAnimationFram來實現,代碼以下:測試
1 btn2.on('click', function(e) { 2 container.css("display","block"); 3 requestanimationframe(function(){ 4 container.css("opacity","1"); 5 }); 6 });
requestAnimationFram的做用是將opacity的操做推遲到下一個tick中處理,從而將display的操做分隔開,基本原理與setTimeout相同。動畫
另外,關於display爲什麼會破壞transition動畫,目前本人仍未找到相關資料來證實其內部機制,個人我的理解是,display的操做會觸發瀏覽器的reflow操做,而transition支持的效果只是觸發瀏覽器的repaint操做,回到上面的demo,若是咱們經過visibility屬性來控制顯示與隱藏,則不會破壞transition的效果。因此,能夠暫時這麼認爲:reflow與repaint的混合會破壞transition的動畫效果,至於更深層次的緣由嘛,借我借我一雙慧眼吧~spa