解決多場景/多端的頁面滾動縮放組件-ScrollerJS

ScrollerJS是什麼

ScrollerJS是用於純邏輯的滾動縮放組件,它獨立於任何指定的渲染或者事件系統。上面是官方定義的,我再說一下我對這個庫的理解,此次我使用ScrollerJS主要是在處理移動端的頁面滾動,不使用Scroller庫的話,咱們用原生的方法實現這種效果的話,就是監聽頁面的touch事件,其實頁面自己就是在監聽touch事件,實現頁面跟隨手勢去移動。如今假設咱們實現的效果是,相似於native app那種左右頁面滑動的效果,依靠默認的touch事件確定是不夠的,咱們一般的作法就是主動監聽touch事件,修改touch事件默認的操做,這樣就能夠利用自帶的touch事件實現本身的滾動縮放的需求。ScrollerJS幫咱們作的就是這樣的事情,你們能夠打開 https://my.browser.miui.com/ ,右鍵F12切換成移動端模式,能夠看到咱們在滾動頁面時,滾動是有慣性的,好比咱們還須要作一個下拉刷新什麼的,本身實現仍是比較麻煩,ScrollerJS應用而生,咱們在touch事件中調用ScrollerJS提供的事件,完成這一套豐富而又強大的功能html

特性

  • 可自定義啓用/禁用x軸和y軸的滾動git

    • 就是說能夠自定義頁面是否能在這倆軸滾動
  • 減速(當用戶動做結束時減速)github

    • 移動端touch後的慣性
  • 彈跳(彈回邊緣)canvas

    • 拖動頁面一直往下拉,鬆手後,頁面相似於小球掉地上,一直與邊緣減速碰撞以致靜止
  • 分頁(對齊整頁寬度/高度)
  • 捕捉(捕捉到用戶可定義的像素網格)
  • 縮放(自動居中縮放或基於視圖中具備可配置的最小/最大縮放的點)
  • 鎖定(根據初始移動鎖定拖動方向)
  • 下拉刷新
  • 可配置是否應使用動畫。

頁面滑動配置對象

這些是可用選項及其默認值。可使用第二個構造函數參數或在運行時經過修改scrollerObj.options.optionName來修改選項。
clipboard.png數組

使用方法

首先看一下簡易demo:

// 第一步,實例化滾動對象
var scrollerObj = new Scroller(function(left, top, zoom) {
    // apply coordinates/zooming
}, {
    scrollingY: false
});

// Configure to have an outer dimension of 1000px and inner dimension of 3000px
scrollerObj.setDimensions(1000, 1000, 3000, 3000);

代碼其實仍是蠻簡單的,首先咱們初始化一個滾動的實例,Scroller構造函數擁有兩個參數,第一個是一個負責管理頁面滾動時須要處理事務的函數,這個函數接受三個參數,分別表示當前頁面左移,向上移,縮放比信息。第二個參數是,頁面滾動相關的配置對象,經過這個對象,咱們能夠聲明頁面如何滾動等,具體參數見上面的總結。這樣咱們就實例化了一個滾動對象。接着看下面那行代碼:瀏覽器

scrollerObj.setDimensions(clientWidth, clientHeight, contentWidth, contentHeight);

這行代碼的意思是,讓咱們設置頁面滾動的區域,以及頁面滾動內容的長度。咱們普通狀況下,出現頁面滾動是由於咱們的頁面內容太多,纔出現的這種狀況,如今咱們要覆蓋原生的這種邏輯,實現起來固然不一樣,咱們既然要滑動頁面,那就不是經過判斷頁面的內容是否溢出,而是直接指定,咱們頁面的滾動內容長度是多少。app

自此,咱們已經定義好了頁面該以怎樣的方式進行移動,以及頁面滾動的區域和大小。可是如今咱們仍是無法移動,爲何呢,就是我開頭說的,咱們須要監聽原有的touch事件,在焉有的touch事件中,加入ScrollerJS的邏輯。框架

接着咱們明確一下,ScrollerJS自帶了哪些事件?

- doMouseZoom(wheelDelta, timeStamp, pageX, pageY)
- doTouchStart(touches, timeStamp)
- doTouchMove(touches, timeStamp, scale)
- doTouchEnd(timeStamp)

注意,對於移動端,咱們須要傳遞給doTouch* 這些方法原生的touches對象數據(native touches event data)。這是什麼意思呢,挖個坑後面講一下。對於使用鼠標的PC端,咱們傳遞一個只含有一個元素的數組,模擬這種狀況:dom

Touch device: doTouchMove(e.touches, e.timeStamp);       // 移動端涉及多指觸摸,因此存在touches
Mouse device: doTouchMove([e], e.timeStamp);   // PC端,固然不存在多指,因此經過這種hack方式解決問題

最後咱們須要使用鼠標滾輪進行縮放的話,能夠這麼使用:函數

doMouseZoom(e.wheelDelta, e.timeStamp, e.pageX, e.pageY);

說了這麼多,其實你會發現我依然是在講一些基礎的概念,你可能會問,爲啥頁面還沒動起來呢?往下看

讓頁面動起來

前面講了一大堆,其實只是分爲兩部分,第一部分闡述了ScrollerJS是什麼,能幹什麼。第二部分闡述了實例ScrollerJS一個對象,要經歷那幾步,替你們總結一下:

  1. var scrollerObj = new Scroller(function(left, top, zoom){}, configObj);
  2. 聲明滾動區域信息: scrollerObj.setDemensions(clientWidth, clientHeight, contentWidth, contentHeight);
  3. 讓頁面動起來。

咱們經過在自帶的touch事件種綁定ScrollerJS提供的方法,實現自定義滾動:

var body = document.body, // 我隨便用的body,你們用啥都行,由於scrollerJS能夠經過setDemensions建立局部滾動區域
    clientWidth = window.innerWidth,
    clientHeight = window.innerHeight,
    contentWidth = window.innerwWidth * 5,
    contentHeight = window.innerHeight;
    
body.addEventListener('touchstart', e => {
    doTouchStart(e.touches, e.timeStamp);
}, false);

body.addEventListener('touchmove', e => {
    doTouchMove(e.touches, e.timeStamp, e.scale);
}, false);

body.addEventListener('touchend', e => {
    doTouchEnd(e.timeStamp);
}, false);

自此,咱們的頁面就滾動起來了,前面挖了個坑尚未填,問題是,爲何要強調用原生touch事件對象的touches呢。那是由於,咱們在使用createjs,PixiJS這種canvas框架時,頁面的滾動其實在引入框架的時候,已是被覆蓋掉了。咱們正常的move事件是不能被觸發的,拿createjs舉例,頁面的滾動應該監聽舞臺stage的stagemousemove移動事件,這個時候上面的代碼就變成了:

stage.addEventListener('stagemousedown', e => {
        doTouchStart(e.nativeEvent.touches, e.timeStamp);  // 這裏的e.nativeEvent纔是頁面原生事件對象
    }, false);
    
    stage.addEventListener('stagemousemove', e => {
        doTouchMove(e.nativeEvent.touches, e.timeStamp, e.scale);
    }, false);
    
    stage.addEventListener('stagemouseup', e => {
        doTouchEnd(e.timeStamp);
    }, false);

能夠看到,stagemousemove等三個事件傳入的e事件對象,實際上是createjs本身構造的一個事件對象,並非瀏覽器本身的那一套,因此咱們須要調用nativeEvent來進行touches的傳遞

總結

ScrollerJS不只能解決平常滾動縮放相關的邏輯難點,也能在canvas等平臺大放異彩,自定義滑動效果當之無愧首選。更多內容請轉移
GitHub:https://github.com/parkeeers/...
在線Demo:http://zynga.github.com/scrol... http://zynga.github.io/scroll...

相關文章
相關標籤/搜索