原生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>
目录
相关文章
|
2月前
|
缓存 JavaScript 前端开发
高效打造跨平台桌面应用:Electron加载服务器端JS
【9月更文挑战第17天】Electron 是一个基于 Chromium 和 Node.js 的开源框架,允许使用 HTML、CSS 和 JavaScript 构建跨平台桌面应用。加载服务器端 JS 可增强应用灵活性,实现代码复用、动态更新及实时通信。通过 HTTP 请求、WebSocket 或文件系统可实现加载,但需注意安全性、性能和兼容性问题。开发者应根据需求选择合适方法并谨慎实施。
123 3
|
3天前
|
缓存 前端开发 JavaScript
优化CSS和JavaScript加载
Next.js和Nuxt.js在优化CSS和JavaScript加载方面提供了多种策略和工具。Next.js通过代码拆分、图片优化和特定的CSS/JavaScript优化措施提升性能;Nuxt.js则通过代码分割、懒加载、预渲染静态页面、Webpack配置和服务端缓存来实现优化。两者均能有效提高应用性能。
|
10天前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
17 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
2月前
|
移动开发 前端开发 JavaScript
原生JavaScript+canvas实现五子棋游戏_值得一看
本文介绍了如何使用原生JavaScript和HTML5的Canvas API实现五子棋游戏,包括棋盘的绘制、棋子的生成和落子、以及判断胜负的逻辑,提供了详细的代码和注释。
34 0
原生JavaScript+canvas实现五子棋游戏_值得一看
|
3月前
|
编解码 缓存 算法
Three.js如何降低3D模型的大小以便更快加载
为加快600MB的3D模型在Three.js中的加载速度,可采用多种压缩方法:1) 减少顶点数,使用简化工具或LOD技术;2) 压缩纹理,降低分辨率或转为KTX2等格式;3) 采用高效文件格式如glTF 2.0及draco压缩;4) 合并材质减少数量;5) 利用Three.js内置优化如BufferGeometry;6) 按需分批加载模型;7) Web Workers后台处理;8) 多模型合并减少绘制;9) 使用Texture Atlas及专业优化工具。示例代码展示了使用GLTFLoader加载优化后的模型。
396 12
|
3月前
|
Devops 持续交付 测试技术
JSF遇上DevOps:开发流程将迎巨变?一篇文章带你领略高效协同的魅力!
【8月更文挑战第31天】本文探讨了如何在JavaServer Faces(JSF)开发中融入DevOps文化,通过持续集成与部署、自动化测试、监控与日志记录及反馈机制,提升软件交付速度与质量。文中详细介绍了使用Jenkins进行自动化部署、JUnit与Selenium进行自动化测试、ELK Stack进行日志监控的具体方法,并强调了持续改进的重要性。
38 0
|
3月前
|
JavaScript 前端开发 API
从零开始学表单操作,jQuery 与原生 JavaScript 完全指南,带你轻松掌握网页交互关键!
【8月更文挑战第31天】在网页开发中,表单是实现用户互动的关键元素。无论是收集信息、提交数据还是验证输入,都需要对表单进行有效操作。本文档介绍了如何使用原生 JavaScript 和 jQuery 操作表单,包括获取表单元素、读写表单值、处理表单提交及验证等核心功能。jQuery 提供了更简洁的语法和更好的兼容性,但原生 JavaScript 在性能上有优势。选择合适的方法取决于项目需求和个人偏好。下面通过具体示例展示了两种方式的操作方法。
34 0
|
3月前
|
前端开发 JavaScript Linux
【Azure 应用服务】在Azure App Service for Linux环境中,部署的Django应用,出现加载css、js等静态资源文件失败
【Azure 应用服务】在Azure App Service for Linux环境中,部署的Django应用,出现加载css、js等静态资源文件失败
|
3月前
|
JavaScript 前端开发
JavaScript引入全攻略:提升网页加载速度的秘诀!
JavaScript引入全攻略:提升网页加载速度的秘诀!
|
3月前
|
资源调度 JavaScript 前端开发
如何大幅减少 Vue.js 中的包大小和加载时间,提升用户体验!
如何大幅减少 Vue.js 中的包大小和加载时间,提升用户体验!