原生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>

此篇文章爲作者原創
如需轉載 請註明出處

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章