在以前,對于動畫除了Jquery的animate等動畫函數(shù)外,更多的是使用setTimeout,setInterval,這樣循環(huán)的去改變一個元素的margin、width、top等屬性。也正是如此,才有了我的困惑。
首先,setTimeout,setInterval 這貨并非你設置0ms它就能一直一直的去執(zhí)行。曾經(jīng)在iscroll里調(diào)試的時候無意中發(fā)現(xiàn)了這個秘密。原來Timer延時的計算依靠的是瀏覽器的內(nèi)置時鐘,而時鐘的精確度又取決于時鐘更新的頻率。IE8及其之前的IE版本更新間隔為15.6毫秒。完了,我想它10ms執(zhí)行1px位移,它還不能準時的干這事。
而卡又是怎么回事呢?卡,因為代碼寫的不好。畢竟js是單線程的,一旦有耗時的動作那么UI就可能不響應了。雖然我們使用了setTimeout,但正是因為setTimeout讓我們看上去界面沒死可動作卻又不流暢了。因為這次setTimeout執(zhí)行之后,在下次執(zhí)行前,中間這個間隔里很可能遇到另一個耗時的動作,那么,setTimeout的執(zhí)行就無限后延。然后呢?卡!然而,卡還能有下一個原因,改變原始屬性時不小心觸發(fā)瀏覽器Layout(即:重布局)。這個問題說它不耗時呢,卻又耗時,說它耗時呢,很多時候卻又可以忽略。但很多時候其實是不能忽略的。
除了上面這兩段,還有一個問題,就是在很多手機上總感覺是一幀一幀的,而且還可能是一幀長一幀短。這真是能把人都搞廢的節(jié)奏。為何會這樣呢,依然和settimeout的推遲有一定的關系。丟幀。這個問題有涉及到顯示器的刷新頻率問題。實在太復雜了。
最后選擇了CSS3,js動態(tài)的改變元素的屬性,使用transition來控制動畫執(zhí)行時間。舉個例子:
代碼如下:
js:
代碼如下:
$("#test").width(200);
這樣1秒之后這個div的寬度會變成200px。不是孫悟空變桃子一樣瞬間變大,慢慢的趕腳,不卡不頓。而且使用css動畫有個好處,它不受耗時js的影響。雖然瀏覽器中UI線程與js線程是互斥,但這一點對css動畫不成立,并且很多瀏覽器還能啟用硬件加速(比如:Chrome)。雖然瀏覽器重布局普通情況下感覺不是很明顯,但還是應該盡量避免大面積的重布局。so在動畫元素上加上-webkit-transform: translateZ(0);或者-webkit-transform: translate3d(0,0,0);這樣瀏覽器會獨立渲染這一層。即便是重布局無法避免,這樣面積也小些。而使用translate取代margin也確實是一個十分明智的決定。
最后附上一些常用的改變時會觸發(fā)重布局的屬性:
代碼如下:
width
height
padding
margin
display
border-width
border
min-height
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com