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

简介: 这是手机端常见的一个功能,可能很多人都是用框架或者插件实现。这里,我试着用原生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>

会得到这样一个网页,头部底部固定,中间部分可滑动12.png


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


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


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


13.png

看到这个图,我们就知道要做什么了

 //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>
目录
相关文章
|
15天前
|
JSON JavaScript 前端开发
JavaScript原生代码处理JSON的一些高频次方法合集
JavaScript原生代码处理JSON的一些高频次方法合集
|
2月前
|
JavaScript
原生js实现复选框(全选/全不选/反选)效果【含完整代码】
原生js实现复选框(全选/全不选/反选)效果【含完整代码】
52 1
|
15天前
|
JavaScript 算法
原生JS完成“一对一、一对多”矩形DIV碰撞检测、碰撞检查,通过计算接触面积(重叠覆盖面积)大小来判断接触对象DOM
原生JS完成“一对一、一对多”矩形DIV碰撞检测、碰撞检查,通过计算接触面积(重叠覆盖面积)大小来判断接触对象DOM
|
3月前
|
前端开发 JavaScript 索引
|
1天前
|
JavaScript 前端开发 UED
深入解析JavaScript原生操作DOM技术
【4月更文挑战第22天】本文深入探讨JavaScript原生DOM操作技术,包括使用`getElement*`方法和CSS选择器获取元素,借助`createElement`与`appendChild`动态创建及插入元素,修改元素内容、属性和样式,以及删除元素。通过掌握这些技术,开发者能实现页面动态交互,但应注意避免过度操作DOM以优化性能和用户体验。
|
15天前
|
JavaScript 前端开发
EasyUi js 加载数据表格DataGrid
EasyUi js 加载数据表格DataGrid
|
15天前
|
JavaScript
【归总】原生js操作浏览器hash、url参数参数获取/修改方法合集
【归总】原生js操作浏览器hash、url参数参数获取/修改方法合集
|
19天前
|
JavaScript
理解DOM树的加载过程(js的问题)
理解DOM树的加载过程(js的问题)
|
1月前
|
JavaScript
js判断图片是否加载完成
js判断图片是否加载完成
24 0
|
2月前
|
缓存 JavaScript 前端开发
前端工程化:优化JS加载速度
在现代Web应用中,JavaScript已成为必不可少的一部分,但是随着业务复杂度的增加,JS文件的体积也越来越大,导致网页加载速度变慢,影响用户体验。本文将介绍前端工程化的优化策略,以提高JS文件的加载速度。
18 2