Iscroll解析

作了一些移動端的產品,發現一些滾動效果不少會使用 iscroll 做爲底層庫(如阿里小蜜)。iscroll 的文檔已經很久沒更新了,並且比較簡單,常常須要直接讀源碼。這裏寫一篇總結,做爲對 iscroll API的整理。而 iscroll 的庫 probe,lite,zoom,infinite 和標準庫等多個版本,而 probe 是平時運用的比較多的一個庫,除了 iscroll 的標準庫以外,還有 snap(廣義翻頁) 功能。這裏主要以 probe 作整理。去掉裏面的 scrollbars/indicators 部分,由於這兩部份內容通常視覺不會有太多要求。但這一部分的內容在 iscroll 庫中和 iscroll 的主體內容同等地位,我的以爲沒有必要。css

Iscroll的核心

仔細想一想,若是咱們要實現相似功能的觸控庫,咱們會怎麼作?正常思路大概就是:css3

檢測 ->  處理數據 -> 產生位移

思路大概就是這樣,和現實生活中的控制很相似:經過傳感器檢測數據,而咱們這裏的檢測設備就是註冊的一系列事件。檢測到的數據每每屬於原始數據,沒有辦法直接使用,這裏就須要進行相應的處理。處理完後,就須要滾動屏幕,對應到實現就是操做 dom 的位置屬性。api

仔細看了一下 iscroll 的源碼,果真也是採用相似的思路,一下是 iscroll 核心處理邏輯:
app

  • 檢測dom

首先,iscroll 檢測是每次初始化的時候,經過 HandEvent 註冊一系列的函數。爲了同時兼容無線和 PC 等多個端,同一類型的事件須要註冊多個。簡單的分有如下幾類:函數

  • start 類型事件,如:touchstart,pointerdown,MSPointerDown,mousedown.性能

  • move 類型事件,如:touchmove,pointermove,MSPointerMove,mousemove。spa

  • end 類型事件,如:touchend,pointerup,touchcancel等。code

除了以上三個,還有 transitionend,wheel,keydown,click 等一系列事件。orm

  • 處理函數
    處理函數都是和檢測事件對應的,每一類檢測事件都有相應的處理函數。如:

    • _start(e) 函數對應 start 類型事件。

    • _move(e) 函數對應 move 類型事件。

    • _end(e) 函數對應 end 類型事件。

除此以外,還有 _transitionEnd(e),_wheel(e),_key(e) 等處理函數。

  • 運動函數
    處理函數處理好相應數據和邏輯以後,會在處理函數中調用運動相關的函數。而運動相關的函數主要作一些位移變換,iscroll 對這些位移變換作了不少兼容性的處理。

    • _translate( x, y) 是平移運動的核心函數。其中支持 transform 和 "left" 兩種移動方式。

    • _animate(destX, destY, duration, easingFn) 是帶 "transtion" 效果的運動函數,當不支持或關閉 transtion 調用該函數。此函數基於 requestAnimationFrame 作位置移動。

    • 除了這兩個內部運動函數以外,iscroll 還提供了 scrollBy,scrollTo,scrollToElement,goToPage,next,prev 等一系列的 API 供外部調用。

配置

var myScroll = new IScroll('#wrapper', {
    mouseWheel: true,
    scrollbars: true
});

初始化出入的第二個參數爲配置,會掛載到 myScroll 的 options 屬性上。

  • HWCompositing:是否採用 3D 加速,同時 iscroll 內部還會對客戶端是否支持 perspective 屬性共同決定。

  • useTransition:是否採用 css3 的 transition,同時 iscroll 內部還會對客戶端是否支持該屬性共同決定。

  • useTransform:是否採用 css3 的 transform,同時 iscroll 內部還會對客戶端是否支持該屬性共同決定。

  • tap,click:iscroll 中的兩個自定義事件,配置爲 string,須要執行的自定義事件。

  • eventPassthrough:默認爲 undefine,爲 true 時,關閉默認方向滾動(scrollY)。

  • bindToWrapper:默認爲undefine,控制初始化事件綁定到什麼對象上。爲 true 時,會將 touch, mousemove 等事件綁定到 iscroll 的 dom 對象。不然,綁定到 window 上。

  • preventDefault:默認爲 true,在各個運動函數中和其餘值配合使用。eventPassthrough 爲 true 時,設置爲 false.

  • preventDefaultException:默認值 /^(INPUT|TEXTAREA|BUTTON|SELECT)$/,和preventDefault,即內部函數isBadAndroid配合使用,在各個運動函數中執行。

  • scrollY,scrollX:,初始值爲 y 軸方向滾動,即 scrollY 爲 true.

  • freeScroll:默認爲 flase,scrollX 和此值同時設置爲 true 時,可想任意方向滾動。

  • directionLockThreshold:默認值爲 5,鎖定方向的一個閥值,一個方向持續滑動超過這個閥值以後,纔會鎖定另外一方向,通常不須要改動。

  • resizePolling:默認值 60ms,控制下拉刷新時間。

  • probeType:默認爲 undefine, 可設置爲1,2,3。主要用於開啓監聽 scroll, 值越大靈敏度越高,越耗性能。

  • momentum:默認爲 true,運動的物理引擎,對性能有影響,可關閉。

  • snap:默認爲 undefine,設置爲 true 後,可按必定步長移動。

  • snapSpeed:默認爲 300ms,transitionTime 的時間。

  • snapStepX,snapStepY:默認爲 iscroll 的高度或寬度,可設爲某一數字,按照相應距離移動。

  • snapThreshold:默認爲0.334,移動到下一步長的閥值係數,此值乘對應頁的寬或高。

  • bounce:默認true,是否開啓彈動效果。

  • bounceEasing:默認爲 circular,彈動效果。

  • bounceTime:默認600ms, 彈動事件

  • disableMouse,disablePointer,disableTouch:默認爲 undefine, 設爲 true 時,初始化時會不註冊相應事件,達到不響應的效果。

  • mouseWheel:默認爲 undefine,設置爲 true 後,開啓滑輪。

  • mouseWheelSpeed:默認爲 20ms。

  • invertWheelDirection:滾動輪方向,無特殊狀況不用關注。

  • keyBindings 默認爲鍵值對,可設置{down: 40},對應的向下鍵,向下移動。

方法

  • destroy(): destory只會銷燬全部綁定事件,並不會銷燬 iscroll。可經過 iscroll = null 對 iscroll進行銷燬。此函數還會觸發 destory 事件。

  • refresh():調整容器位置,[注意]每次新增或刪除 dom 節點後需調用此方法。

  • on(type, fn):註冊 isroll 事件,可註冊的函數類型爲下一小節函數。

  • off(type, fn):銷燬事件。
    resetPosition(time):重置到初始位置。time 爲 動效時間。

  • disable():靜止滑動

  • enable ():可滑動。

  • scrollBy(x, y, time, easing):增長多少像素滑動。

  • scrollTo(x, y, time, easing):滾動到某一像素。

  • scrollToElement(el, time, offsetX, offsetY, easing):滾動到某一元素。

  • getComputedPosition():得到計算以後的位置,主要鍵盤中使用。

  • goToPag(x, y, time, easing):滾動到某一頁,snap 中使用。

  • next():滾動到下一頁,snap 中使用。

  • prev():滾動到上一頁,snap 中使用。

監聽事件

  • beforeScrollStart

  • scrollStart

  • scrollCancel

  • scroll

  • scrollEnd

  • destroy

  • refresh

侷限

iscroll 有不少優勢,最主要的是相對穩定,還有一系列兼容性處理。但他有一些侷限性,主要的侷限性是它的可擴展性較差。一個栗子:當咱們想對某一元素進行拖拽時,會發現很難用 iscroll。而產生這一問題的主要緣由時:iscroll 的 scroll 等監聽事件是在元素移動時纔會觸發。也就說 iscroll 沒有暴露出觸控 api 給用戶使用。

相關文章
相關標籤/搜索