原生js滾動到底部加載數據和下拉刷新 Scrollload

原文地址 https://github.com/fa-ge/Scrollload/blob/master/README.mdjavascript

初衷

現在移動端站點愈來愈多,滾動到底部加載數據和下拉刷新的需求很是的常見,即便如今不少pc站點也會有這樣的需求,好比百度首頁就有。雖然簡單的完成這麼一個功能很是方便,可是滾動每每會成爲性能的瓶頸,處理很差滾動頗有可能會不流暢。既然不少頁面和項目都須要,固然最須要有一個複用性高的插件。可是我卻一直沒找到特別好用的插件,有些須要依賴jquery,但貌似編寫這樣的插件時jquery並無帶來任何的便利。css

Scrollload.js介紹

Scrollload是一個無依賴,體積極小(壓縮+gzip後不到3k),可配置性高(能夠自定義加載時候動畫,加載完後的dom,提早加載的距離),可擴展性強大(很方便作到指定容器內的滾動,多tab的滾動,異常處理,刷新從新加載等),性能好(在滾動的時候作了一些性能優化,如緩存window的高度,函數節流)的js插件。源碼地址: https://github.com/fa-ge/Scro...html

解決的痛點

  1. 無依賴,配置簡單,有多套滾動加載效果可選(須要單獨引入對應的css,固然也有默認效果)java

  2. 支持下拉刷新jquery

  3. 在ios中,全局滾動會有不少很差的體驗,我認爲是能夠用局部滾動來替代全局的。局部滾動也會有幾個坑,但都是可解決的,也就是說全局滾動的坑目前還很難解決。該插件內置局部滾動坑的解決方案,方便使用局部滾動替代全局滾動且無反作用。具體見ios局部滾動的坑及解決方案ios

兼容性

不支持ie8及如下瀏覽器。git

示例

無任何效果github

有loading動畫一(百度移動端包括下拉刷新)ajax

有loading動畫二npm

多個tab效果

div容器中的滾動加載

左右滑動tab而且滾動加載——複雜示例

異常處理

點擊刷新從新加載

示例源碼

安裝

npm install scrollload --save

使用

若是你沒有用模塊管理, 直接從window對象下取Scrollload對象也是能夠的,打包後的js放在lib目錄下,能夠直接用script標籤引入
同時支持模塊引入

//ES6
import Scrollload from 'Scrollload'
//commonjs
const Scrollload = require('Scrollload').default

固然也支持amd,不過我沒用過。
真正用起來也很是簡單。記住一點。插件會把底部DOM插入到container最後一個子節點以後。

你的dom結構是如下這樣的

<div class="scrollload-container">
    <ul class="scrollload-content">
        <li></li>
    </ul>
</div>

插件會把底部DOM就會被插在ul標籤的後面。你能夠按照你之前的方式操做dom。demo中我都是用這種方式來作的。 我

下面是js中的使用。

let page = 1
new Scrollload({
      // container 和 content 兩個配置的默認取的scrollload-container和scrollload-content類的dom。只要你按照以上的dom結構寫,這兩個配置是能夠省略的
      container: document.querySelector('.scrollload-container'),
    content: document.querySelector('.scrollload-content'),
    loadMore: function(sl) {
        
        if (page === 6) {
          // 沒有數據的時候須要調用noMoreData
            sl.noMoreData()
            return
        }

        // 我這裏用jquery的不是由於須要jquery,只是jquery的語法看起來比較簡單。你們都認識。
        // 若是你不是用jquery,能夠看看原生的insertAdjacentHTML方法來替代append
        $.ajax({
            type: 'GET',
            url: `http://rap.taobao.org/mockjsdata/14522/getgamelist?page=${page++}`,
            dataType: 'json',
            success: function(data){
                // contentDom其實就是你的scrollload-content類的dom
                $(sl.contentDom).append(data)

                // 處理完業務邏輯後必需要調用unlock
                sl.unLock()
            },
            error: function(xhr, type){
                // 加載出錯,須要執行該方法。這樣底部DOM會出現出現異常的樣式。
                sl.throwException()
            }
        })
    },
    // 你也能夠關閉下拉刷新
    enablePullRefresh: true,
    pullRefresh: function (sl) {
        $.ajax({
            type: 'GET',
            url: `http://rap.taobao.org/mockjsdata/14522/getgamelist?page=1`,
            dataType: 'json',
            success: function(data){
                $(sl.contentDom).prepend(data)

                // 處理完業務邏輯後必需要調用refreshComplete
                sl.refreshComplete()
            }
        })
    }
})

參數列表

// 如下是配置參數及其默認內容     

// 容器
container: document.querySelector('.scrollload-container'),
// 列表內容
content: container.querySelector('.scrollload-content'),
// 視窗(默認是window,若是是局部滾動須要設置滾動的dom)
window: window,
  
// 是否開啓加載更多(默認開啓,若是關閉則滾動到底部則再也不出現加載更多)
enableLoadMore: true,
// 初始化的時候是否鎖定,鎖定的話則不會去加載更多。因爲這個插件實例化後默認是沒有鎖定的因此會去調用loadMore,但其實在多個tab的狀況下是不該該一實例化完後就去調用的。因此有了這個參數。
isInitLock: false,
// 閥值 (滾動到底部提早加載的距離)
threshold: 10,

// 修復局部滾動的兩個坑。參見ios局部滾動的坑及解決方案 https://zhuanlan.zhihu.com/p/24837233
useLocalScrollFix: false,
useScrollFix: false,

// 底部加載中的html
loadingHtml: generateHtml('加載中...'),
// 底部沒有更多數據的html
noMoreDataHtml: generateHtml('沒有更多數據了'),
// 底部出現異常的html
exceptionHtml: generateHtml('出現異常'),
// 加載更多的回調
loadMore: noop,

// 是否開啓下拉刷新
enablePullRefresh: false,
// 頂部下拉刷新的html
notEnoughRefreshPortHtml: generateHtml('下拉刷新'),
// 頂部鬆開刷新的html
overRefreshPortHtml: generateHtml('鬆開刷新'),
// 頂部正在刷新的html
refreshingHtml: generateHtml('正在刷新'),
// 下拉刷新的回調
pullRefresh: noop,
// 到達刷新點的回調(包括向上和向下,能夠經過isMovingDown判斷方向)
arrivedRefreshPortHandler: noop,
// 開始滑動的回調
touchStart: noop,
// 滑動時的回調
touchMove: noop,
// 滑動中鬆開手指的回調
touchEnd: noop,
// 超過可刷新位置後的監聽函數
overRefreshPortHandler: noop,
// 未超過可刷新位置前的監聽函數
notEnoughRefreshPortHandler: noop,

// 計算下拉的阻力函數
calMovingDistance(start, end) {
    return (end - start) / 3
},
// 實例化完後的回調
initedHandler: noop

API

方法
  • lock(): 鎖定後不會調用loadMore方法

  • unLock(): 每次滾動到底部都會鎖定,因此你在loadMoreFn方法中須要解鎖,下次滾動到底部才能繼續調用loadMoreFn

  • noMoreData(): 當你的數據所有加載完後調用這個方法,將顯示沒有更多數據的div,你也能夠配置這個div,用noMoreDataHtml配置參數

  • refreshData(): 當你調用完noData方法後,若是你想刷新當前的數據從新加載就要調用這個方法

  • throwException(): 出現異常須要調用這個方法,會在底部DOM中出現相應的樣式

  • solveException(): 當你的異常問題解決後須要調用這個方法能夠繼續加載數據

  • refreshComplete(): 下拉刷新的時候你去請求完數據後須要調用這個函數通知我。我就能夠把正在刷新的狀態改爲刷新完成。

  • getOptions(): 獲取配置

  • setOptions(obj): 修改配置。obj和new Scrollload()的第二個參數同樣的格式。

  • setGlobalOptions(obj): 全局配置,一次配置屢次時候。調用這個方法和以前的方法不同。以前的都須要對象實例化後才能調用。這個方法直接Scrollload構造函數上調用。Scrollload.setGlobalOptions()。接受的參數和setOptions方法同樣

屬性
  • bottomDom: 底部DOM,包裹着加載中動畫和沒有更多數據的dom對象

  • isLock: 是否爲鎖定狀態

  • hasMoreData: 是否還有更多數據,默認爲true,調用noData方法後爲false

  • container: 你傳進來的container

  • content: 你傳進來的content

  • win: 你傳進來的window

  • isMovingDown: 下拉刷新的時候你滑動的方向

  • isRefreshing: 下拉刷新的時候你是否在刷新中

  • distance: 下拉刷新的時候你滑動的dom移動的距離,不是你手指移動的距離。這二者的關係能夠經過calMovingDistance計算

交流

若是你有好的加載更多動畫的效果,能夠在loading-demos文件夾下寫一些本身的demo,loading的css必須是loading.css,並在頭部加入loadingHtml的dom結構。參考,而後提一個pr給我。

固然用的時候有什麼建議均可以和我提,有什麼不懂得也能夠和我提。任何形式和我提均可以。

相關文章
相關標籤/搜索