如果有寫WebApp的人一定會遇到要對content做scroll的需求。這時候你通常有幾種選擇:
- 把不需要scroll的DOM元件的CSS position屬性設定為fixed,然後依靠device上預設的web browser的scroll功能。這個功能絕對行得通,但是如果是在iOS上的話,你一定會覺得為什麼這個scroll特別黏?就是一做fling的動作,就是沒有其他原生App的scroll的流暢。其實你試試iOS上的Safari,的確就是這個行為沒錯,感覺是特別設計有什麼特殊用意並不清楚。但是很明顯的這個方法對於要求原生App的UI體驗是不夠的。
- iOS5之後的WebBrower有支援一個特別的overflow值,也就是 overflow:scroll 。設定這個之後,超過容器空間的iOS會自動套用原生的scroll功能。也行得通,如果你不打算支援iOS4的話。
- 為了克服以上兩個問題,我的選擇是使用iScroll.js,一個Open Source的JavaScript library。很強大,把scroll模擬的很好,而且也會自動產生捲軸。大致上的原理是使用Timer(window.setTimeout)來模擬scroll,也有支援momentum。但是我一直很疑惑的是怎麼在實際的iOS裝置上的scroll animation的frame rate 竟然或是這麼低呢?好吧,重點就在他用了setTimeout! setTimeout! setTimeout! 所以frame rate低是很正常的啊,大概連15fps都不到吧。這時候想說如果用CSS transition(感謝我曾經在之前的公司present過CSS3)的話應該會順暢很多吧。畢竟transition是native code在做animation,而且適當的trick(就是設定一個完全沒作用的3D Transform)還可以啓動硬體加速,FPS一定可以提升到30以上。於是我打開iScroll的source code:
// Constructor iScroll = function (el, options) { var that = this, doc = document, i; that.wrapper = typeof el == 'object' ? el : doc.getElementById(el); that.wrapper.style.overflow = 'hidden'; that.scroller = that.wrapper.children[0]; // Default options that.options = { hScroll: true, vScroll: true, x: 0, y: 0, bounce: true, bounceLock: false, momentum: true, lockDirection: true, useTransform: true, useTransition: false, topOffset: 0, checkDOMChanges: false, // Experimental // Scrollbar hScrollbar: true, vScrollbar: true, fixedScrollbar: isAndroid, hideScrollbar: isIDevice, fadeScrollbar: isIDevice && has3d, scrollbarClass: '', // Zoom zoom: false, zoomMin: 1, zoomMax: 4, doubleTapZoom: 2, wheelAction: 'scroll', // Snap snap: false, snapThreshold: 1, // Events onRefresh: null, onBeforeScrollStart: function (e) { e.preventDefault(); }, onScrollStart: null, onBeforeScrollMove: null, onScrollMove: null, onBeforeScrollEnd: null, onScrollEnd: null, onTouchEnd: null, onDestroy: null, onZoomStart: null, onZoom: null, onZoomEnd: null };
你看到第22行了嗎?useTransition: false,哇,太令人欣慰了。我什麼都不用改耶。只要把它改成 useTransition: true 就好了耶(但還是要記得把要scroll的DOM加上null 3D transform)。果然一改完就很順。省了我很多時間:)
強悍
回覆刪除