博客 / 詳情

返回

基於zepto的移動端上拉刷新小插件

上次開發筆記裏《基於zepto和WeUI的H5頁面開發筆記》提到上拉刷新功能,這是很基本很常用的功能,為了下次自己更便捷的使用,便簡單的封裝了一下 KScroll.js

簡單樣例

這裏先上一個基於zepto和WeUI的列表上拉刷新的例子:

image.png

demo.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
    <title>基於WeUI和zepto.js的列表上拉刷新樣例</title>
    <!-- 引入 WeUI CDN 鏈接 -->
    <link rel="stylesheet" href="https://res.wx.qq.com/t/wx_fed/weui-source/res/2.5.6/weui.css" />
    <!-- 引入 zepto CDN 鏈接 -->
    <script src="https://cdnjs.gtimg.com/cdnjs/libs/zepto/1.1.4/zepto.js"></script>
    <!-- 引入 自定義滾動刷新 -->
    <script src="./KScroll.js"></script>
    <style>
        html,
        body {
            height: 100%;
        }

        .container {
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            overflow: hidden;
            color: var(--weui-FG-0);
        }

        .page {
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            overflow-y: auto;
            -webkit-overflow-scrolling: touch;
            box-sizing: border-box;
            z-index: 1;
        }

        .page__bd {
            height: 100%;
            overflow: hidden;
        }

        .part-content {
            padding: 5px;
        }

        .g-scroll-container {
            height: 60%;
            border: 1px solid #e5e5e5;
            overflow: auto;
        }
    </style>
</head>

<body data-weui-theme="light">
    <div class="container" id="container">
        <div class="page">
            <div class="page__bd">
                <!-- 第二個tab的panel內容 -->
                <div style="height: 40%;">
                    <div class="part-content">
                        <h5>上拉刷新樣例</h5>
                        const ks = <b>new KScroll</b>(option);<br />
                        <b>option:</b><br />
                        containerEle //滾動內容的容器元素<br />
                        contentEle //滾動的內容元素<br />
                        loadMoreEle //滾動的內容裏的最後的加載更多的元素<br />
                        <b>pullToRefresh</b> //加載下一頁的數據的鈎子函數<br />
                        //加載完渲染完,回調<b>ks.refreshed(page,isEnd)</b>更新狀態
                        <br />
                    </div>
                </div>
                <div class="g-scroll-container">
                    <div class="weui-cells g-scroll-content">
                        <div role="option" class="weui-cell ">
                            <div class="weui-cell__bd">
                                <p>標題文字1</p>
                            </div>
                        </div>
                        <div role="option" class="weui-cell ">
                            <div class="weui-cell__bd">
                                <p>標題文字2</p>
                            </div>
                        </div>
                        <div role="option" class="weui-cell ">
                            <div class="weui-cell__bd">
                                <p>標題文字3</p>
                            </div>
                        </div>
                        <div role="option" class="weui-cell ">
                            <div class="weui-cell__bd">
                                <p>標題文字4</p>
                            </div>
                        </div>
                        <div role="option" class="weui-cell ">
                            <div class="weui-cell__bd">
                                <p>標題文字5</p>
                            </div>
                        </div>
                        <div role="option" class="weui-cell ">
                            <div class="weui-cell__bd">
                                <p>標題文字6</p>
                            </div>
                        </div>
                        <div role="option" class="weui-cell ">
                            <div class="weui-cell__bd">
                                <p>標題文字7</p>
                            </div>
                        </div>
                        <div role="option" class="weui-cell ">
                            <div class="weui-cell__bd">
                                <p>標題文字8</p>
                            </div>
                        </div>

                        <div role="alert" class="weui-loadmore">
                            <span aria-hidden="true" role="img" aria-label="加載中" class="weui-primary-loading">
                                <i class="weui-primary-loading__dot"></i>
                            </span>
                            <span class="weui-loadmore__tips">正在加載</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script type="text/javascript">
       // 引入下面js
    </script>
</body>

demo.js

$(function () {

    const pageInfo = {
        total: 3,
        pageSize: 8
    }

    const ks = new KScroll({
        containerEle: $('.g-scroll-container')[0], //滾動內容的容器元素
        contentEle: $('.g-scroll-content')[0], //滾動的內容元素
        loadMoreEle: $(".g-scroll-container .weui-loadmore")[0], //滾動的內容裏的最後的加載更多的元素
        pullToRefresh: function (toPage) {
            //加載下一頁的數據渲染,並回調 gs.refreshed(page,isEnd)
            setTimeout(function () {
                let addHtmlStr = '';
                for (let index = 0; index < pageInfo.pageSize; index++) {
                    addHtmlStr += ` <div role="option" class="weui-cell  weui-cell_example">
                                <div class="weui-cell__bd">
                                    <p>標題文字${(toPage-1)*pageInfo.pageSize+index+1}</p>
                                </div>
                            </div>`;
                }
                $(ks.option.loadMoreEle).before(addHtmlStr);
                ks.refreshed(toPage, toPage == pageInfo.total);
            }, 1500);
        }
    });

});

KSCroll.js

基於zepto的簡單的上拉刷新插件,前提為調用者在界面添加了loadmore的元素。
KScroll主要是
1、監聽touch事件,判斷是否滾動到了底部;
2、達到加載下一頁的條件則回調pullToRefresh函數,調用者在這請求數據刷新DOM;
3、最後調用者調用refreshed方法更新上拉刷新的狀態(數據是否已經加載完畢),KScroll判斷如果是結束狀態則隱藏loadmore元素。

const KScroll = function (opt) {

    const _this = this;

    _this.option = {
        containerEle: $('.kscroll-container')[0],
        contentEle: $('.kscroll-content')[0],
        loadMoreEle: $(".kscroll-container .weui-loadmore")[0],
        touchStatus: 0, // 0 init 1 move 當前狀態,move為正在touchmove
        page: 1, //頁數
        scrollToNext: false, //滾動滿足刷新下一頁的標誌
        isEnd: false, //是否已經滑到底部了,用於判斷是否處理滾動 (如果只有一頁,需設置為true,無需滾動加載)
        loading: false, //正在加載中標誌
        pullToRefresh: undefined //滿足滑動刷新加載數據的回調函數
    };

    _this.option = Object.assign({}, _this.option, opt);

    //加載數據刷新後回調
    _this.refreshed = function (page, isEnd) { //page 加載的頁數 isEnd 是否已經加載到底部了
        _this.option.loading = false;
        if (isEnd) {
            _this.option.isEnd = true;
            $(_this.option.loadMoreEle).remove();
        }
    }

    //初始化動作(監聽touch事件)
    _this.init = () => {

        //監聽手指初始觸碰
        $(_this.option.contentEle).on("touchstart", function (e) {
            if (_this.option.isEnd) return;
            _this.option.touchStatus = 1;
        });

        //判斷向上時,如果滾動條在頂部,那麼逐漸增加上拉刷新的高度
        $(_this.option.contentEle).on("touchmove", function (e) {

            if (_this.option.isEnd) return;

            if (!_this.option.scrollToNext) {

                var aa = $(_this.option.containerEle).height();
                var bb = $(this).scrollTop();
                var cc = $(this).height();
                var dd = aa - bb - cc;

                if (dd < 50) {
                    _this.option.scrollToNext = true;
                }
            }
        });

        //上拉刷新高度達到一定值之後刷新頁面
        $(_this.option.contentEle).on("touchend", function (e) {
            if (_this.option.isEnd) return;
            if (_this.option.touchStatus == 1 && _this.option.scrollToNext && !_this.option.loading) {
                _this.option.loading = true;
                _this.option.page++;
                _this.option.pullToRefresh && _this.option.pullToRefresh(_this.option.page);
                _this.option.scrollToNext = false;
            }
            _this.option.touchStatus = 0;
        });

    }

    _this.init(); //初始化動作(監聽touch事件)

}

其他

本文只是自己寫的沒有動畫的簡單的(基於zepto.js的)上拉刷新插件。
關於下拉刷新(帶回彈動畫)我看了一個效果看着還不錯的(基於原生js的)《寫了一個下拉刷新插件》,親們需要可參考,謝謝作者,在這我也mark一下。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.