水平動畫大概有這個幾個方法:css
margin-left
,常見於輪播圖translateX
,過渡效果好,複雜多坑scrollLeft
,簡單但不支持css3動畫很容易實現,可是須要大量JS輔助,且從頭到尾的跳躍性很大,過渡效果不佳,不太推薦。jquery
利用css3動畫,能夠作到很好的過渡效果,尤爲適合輪播圖,能夠無限循環。它能夠很複雜,對於通常的平移動畫,一個animation定義就能夠搞定。css3
特別提下遇到的一個坑。有一個複雜的交互 ,整屏水平滾動,同時其中的元素獨立地移動,因爲二者的時機可能不一致,所以存在視差。出現過這些情況:css3動畫
visibility: visible!important
能夠解決,原理還不清楚,應該和層疊上下文有關,須要挖RFC文檔。translateX
平移後,不能手動向左平移,所以動畫結束後,須要重置translateX
爲0,同時設置scrollLeft
爲合適的平移值。也所以,css裏最好加上transform: translateX(0)
。這個和scrollTop
是一對,兼容性很好,可是,不支持css3動畫。上面提到了,整屏的css3動畫性能比較糟糕,所以使用requestAnimationFrame
這個性能表現更好的方案,這時必須靠scrollLeft
實現平移。固然這樣也有難點:dom
requestAnimationFrame
實現動畫,代碼複雜且不易理解。requestAnimationFrame
,時間是不可控的,並且在移動端,實際運行時間極可能比你預期的長一截。爲了更加精確,能夠經過setInterval
觸發動畫。附兩個requestAnimationFrame
動畫實現:性能
/** 線性方案*/ function scrollToLeft(dom, stop, duration) { // 手機上實際動畫會延長,作一些壓縮 duration *= 0.88; var t1 = performance.now(); var from = dom.scrollLeft(), step = Math.round((stop - from) * 15 / duration); function move() { from += step; if (step > Math.abs(stop - from)) { from = stop; } dom.scrollLeft(from); if (from === stop) { var t2 = performance.now(); } else { window.requestAnimationFrame(move); } } window.requestAnimationFrame(move); } /** 曲線方案 */ function scrollToLeft(dom, stop, duration, onEnd) { var from = dom.scrollLeft(), cosParameter = Math.abs(stop - from) / 2, scrollCount = 0, oldTimestamp = performance.now(), delta = Math.PI / duration; function step (newTimestamp) { scrollCount += delta * (newTimestamp - oldTimestamp); if (scrollCount >= Math.PI) { dom.scrollLeft(stop); if ($.isFunction(onEnd)) onEnd(); return; } var left = stop - Math.round(cosParameter + cosParameter * Math.cos(scrollCount)); dom.scrollLeft(left); oldTimestamp = newTimestamp; window.requestAnimationFrame(step); } window.requestAnimationFrame(step); }
參考:http://stackoverflow.com/questions/21474678/scrolltop-animation-without-jquery動畫