水平动画大概有这个几个方法: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动画