原生js实现上滑加载,下拉刷新

这是手机端常见的一个功能,可能很多人都是用框架或者插件实现。
这里,我试着用原生js实现。
这样能更明白原理与底层实现

首先,布局,模拟初始数据

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Document</title>
    <style>
        body {
            margin: 0;
        }

        html,
        body {
            height: 100%;
        }

        header,
        footer {
            width: 100%;
            height: 40px;
            position: absolute;
            left: 0;
            text-align: center;
            line-height: 40px;
            background: #999999;
            color: #ffffff;
            z-index: 999;
        }

        header {
            top: 0;
        }

        footer {
            bottom: 0;
        }
        ul {
            display: block;
            width: 100%;
            position: absolute;
            top: 40px;
            bottom: 40px;
            overflow: auto;
            list-style: none;
            padding: 0;
            margin: 0;
        }

        ul>li {
            width: 100%;
            height: 40px;
            line-height: 40px;
            text-indent: 20px;
            border-bottom: 1px solid #666666;
            background: #ffffff;
            color: #333333;
        }
        /* 下拉刷新的时候做 */
        #loading{
            width: 100%;
            height: 40px;
            line-height: 40px;
            text-align: center;
            color: #333333;
            transition: all 0.5s;
            position: absolute;
            z-index: 1;
            color: #ffffff;
            background: orange;
            top: 0;
        }
    </style>
</head>

<body>
    <header>
        我是头部
    </header>
    <section id="con">
        <div id="loading">加载中......</div>
        <ul id="list">

        </ul>
    </section>
    <div id="loadEnd">已加载全部数据</div>
    <footer>
        我是尾部
    </footer>
</body>
<script>
	<script>
        //获取数据
        var list = document.getElementById("list");
        function getData() {
            var html = '';
            for (var i = 0; i < 20; i++) {
                html += '<li>我是第' + (i + 1) + '个li</li>';
            }
          list.innerHTML = html;
        }

        //初始加载函数
        window.onload = () => {
            //初始请求数据
            getData();
        }
    </script>
</script>
</html>

会得到这样一个网页,头部底部固定,中间部分可滑动
在这里插入图片描述

接下来,我们来监听ul的滚动事件

list.addEventListener("scroll", function () {
	//这里可以获取到ul距离屏幕顶部的距离,每次滚动都会刷新
	console.log(this.scrollTop);
})

来做一个分析,接下来不要着急写代码

在这里插入图片描述
看到这个图,我们就知道要做什么了

 //ul的高度 不变的 定死的
 let listH = list.clientHeight;
 //所有li总高度
 let contentH = this.childNodes.length * 41;
 //差值
 let diffValue = contentH - listH;
 //距离视窗还有50的时候,开始触发;
  if (this.scrollTop + 50 >= diffValue) {
       console.log('该加载了...')
       getData();
   }

上滑加载完美实现,当我滑到快到最后一个li的时候,触发获取数据的方法
我们再添加一个节流阀,不让它无限加载。

function getData() {
            var html = '';
            for (var i = 0; i < 20; i++) {
                html += '<li>我是第' + (i + 1) + '个li</li>';
            }
            var length = list.children.length;
            if (length === 0) {
                list.innerHTML = html;
            } else if(length > 0 && length < 100){
                //html是字符串 
                var newHtml = parseDom(html);
                //后面插入元素
                insertAfter(newHtml, list.children[length - 1]);
            }else if(length === 100){
                console.log("已经到底了,别拉了");
            }
        }

这里有两个非常重要的方法,都是原生js操作

1.字符串dom化

 //字符串dom化
 function parseDom(arg) {
       var objEle = document.createElement("div");
       objEle.innerHTML = arg;
       return [...objEle.childNodes];
   };

2.在已有元素后面插入元素

 //在已有元素后面插入元素
 function insertAfter(newElement, targetElement) {
      newElement.forEach(element => {
          //在后面插入元素 after:js新的dom api 
          targetElement.after(element)
      });
      return
  }

下拉加载

通过判断ul的scrollTop值,当ul的scrollTop === 0的时候,触发
添加到监听滚动事件里,加一些样式操作即可
有些许粗糙,功能为主,见谅见谅

if(this.scrollTop === 0){
   list.style.top = "80px";
    loading.style.top = "40px";
    //刷新数据
    setTimeout(()=>{
        loading.style.top = "0";
        list.style.top = "40px";
    },1000)
    
}

那么完整代码就是

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Document</title>
    <style>
        body {
            margin: 0;
        }

        html,
        body {
            height: 100%;
        }

        header,
        footer {
            width: 100%;
            height: 40px;
            position: absolute;
            left: 0;
            text-align: center;
            line-height: 40px;
            background: #999999;
            color: #ffffff;
            z-index: 999;
        }

        header {
            top: 0;
        }

        footer {
            bottom: 0;
        }
        ul {
            display: block;
            width: 100%;
            position: absolute;
            top: 40px;
            bottom: 40px;
            overflow: auto;
            list-style: none;
            padding: 0;
            margin: 0;
        }

        ul>li {
            width: 100%;
            height: 40px;
            line-height: 40px;
            text-indent: 20px;
            border-bottom: 1px solid #666666;
            background: #ffffff;
            color: #333333;
        }
        /* 下拉刷新的时候做 */
        #loading,#loadEnd{
            width: 100%;
            height: 40px;
            line-height: 40px;
            text-align: center;
            color: #333333;
            transition: all 0.5s;
            position: absolute;
            z-index: 1;
            color: #ffffff;
        }
        #loading{
            background: orange;
            top: 0;
        }
        #loadEnd{
            background: green;
            bottom: 0;
        }
    </style>
</head>

<body>
    <header>
        我是头部
    </header>
    <section id="con">
        <div id="loading">加载中......</div>
        <ul id="list">

        </ul>
    </section>
    <div id="loadEnd">已加载全部数据</div>
    <footer>
        我是尾部
    </footer>
    <script>
        //获取数据
        var list = document.getElementById("list");
        var loading = document.getElementById("loading");
        var loadEnd = document.getElementById("loadEnd");
        function getData() {
            var html = '';
            for (var i = 0; i < 20; i++) {
                html += '<li>我是第' + (i + 1) + '个li</li>';
            }
            var length = list.children.length;
            if (length === 0) {
                list.innerHTML = html;
            } else if(length > 0 && length < 100){
                //html是字符串 
                var newHtml = parseDom(html);
                //后面插入元素
                insertAfter(newHtml, list.children[length - 1]);
            }else if(length === 100){
                console.log("已经到底了,别拉了");
                list.style.bottom = "80px";
                loadEnd.style.bottom = "40px";
                //加个定时器模拟接口请求结束 隐藏掉此条
                //或者可以插入一条元素 
            }
        }

        //字符串dom化
        function parseDom(arg) {
            var objEle = document.createElement("div");
            objEle.innerHTML = arg;
            return [...objEle.childNodes];
        };
        //在已有元素后面插入元素
        function insertAfter(newElement, targetElement) {
            newElement.forEach(element => {
                //在后面插入元素 js 新的dom api
                targetElement.after(element)
            });
            return
        }

        //初始加载函数
        window.onload = () => {
            //初始请求数据
            getData();
            list.addEventListener("scroll", function () {
                //ul的高度 不变的 定死的
                let listH = list.clientHeight;
                //所有li总高度
                let contentH = this.childNodes.length * 41;
                //下拉刷新
                if(this.scrollTop === 0){
                    list.style.top = "80px";
                    loading.style.top = "40px";
                    //刷新数据
                    setTimeout(()=>{
                        loading.style.top = "0";
                        list.style.top = "40px";
                    },1000)
                }
                //距离
                let diffValue = contentH - listH;
                //ul离顶部的距离
                //距离视窗还有50的时候,开始触发;
                if (this.scrollTop + 50 >= diffValue) {
                    console.log('该加载了...')
                    getData();
                }
            })
        }
    </script>
</body>
</html>

此篇文章为作者原创
如需转载 请注明出处

猜你喜欢

转载自blog.csdn.net/qq_35942348/article/details/102932152