乐趣区

关于前端:基于zepto的移动端下拉刷新小插件

上次开发笔记里《基于 zepto 和 WeUI 的 H5 页面开发笔记》提到下拉刷新性能,这是很根本很罕用的性能,为了下次本人更便捷的应用,便简略的封装了一下 GScroll.js

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="./GScroll.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 gs = <b>GScroll</b>(option);<br />
                        <b>option:</b><br />
                        containerEle // 滚动内容的容器元素 <br />
                        contentEle // 滚动的内容元素 <br />
                        loadMoreEle // 滚动的内容里的最初的加载更多的元素 <br />
                        <b>pullToRefresh</b> // 加载下一页的数据的钩子函数 <br />
                        // 加载完渲染完,回调 <b>gs.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">
        $(function () {

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

            // 下拉滚动刷新
            const gs = GScroll({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>`;
                        }
                        $(gs.loadMoreEle).before(addHtmlStr);

                        gs.refreshed(toPage, toPage == pageInfo.total);

                    }, 1500);
                }
            });

        });
    </script>
</body>

</html>

GScroll.js

const GScroll = function (opt) {

    const basicOption = {containerEle: $('.gscroll-container')[0],
        contentEle: $('.gscroll-content')[0],
        loadMoreEle: $(".gscroll-container .weui-loadmore")[0],
        touchStatus: 0, // 0 init 1 move 以后状态,move 为正在 touchmove
        page: 1, // 页数
        scrollToNext: false, // 滚动满足刷新下一页的标记
        isEnd: false, // 是否曾经滑到底部了,用于判断是否解决滚动 (如果只有一页,需设置为 true,无需滚动加载)
        loading: false, // 正在加载数据的标记
        pullToRefresh: undefined // 满足滑动刷新加载数据的回调函数
    };

    const _thisGS = Object.assign({}, basicOption, opt);

    // 加载数据刷新后回调
    _thisGS.refreshed = function (page, isEnd) { //page 加载的页数 isEnd 是否曾经加载到底部了
        _thisGS.loading = false;
        if (isEnd) {
            _thisGS.isEnd = true;
            $(_thisGS.loadMoreEle).remove();}
    }

    // 监听手指初始触碰
    $(_thisGS.contentEle).on("touchstart", function (e) {if (_thisGS.isEnd) return;
        _thisGS.touchStatus = 1;
    });

    // 判断向上时,如果滚动条在顶部,那么逐步减少下拉刷新的高度
    $(_thisGS.contentEle).on("touchmove", function (e) {if (_thisGS.isEnd) return;

        if (!_thisGS.scrollToNext) {var aa = $(_thisGS.containerEle).height();
            var bb = $(this).scrollTop();
            var cc = $(this).height();
            var dd = aa - bb - cc;

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

    // 下拉刷新高度达到肯定值之后刷新页面
    $(_thisGS.contentEle).on("touchend", function (e) {if (_thisGS.isEnd) return;
        if (_thisGS.touchStatus == 1 && _thisGS.scrollToNext && !_thisGS.loading) {// console.log(` 申请第 ${_thisGS.page} 列表数据 `);
            _thisGS.loading = true;
            _thisGS.page++;
            _thisGS.pullToRefresh && _thisGS.pullToRefresh(_thisGS.page);
            _thisGS.scrollToNext = false;
        }
        _thisGS.touchStatus = 0;
    });

    return _thisGS;
}
退出移动版