js 前端實現下拉重新整理 上拉載入
阿新 • • 發佈:2022-03-28
效果
css
/* 下拉重新整理 */ .refresh-loading { transition: all 300ms ease 0s; height: 0; padding-top: 10px; overflow: hidden; } .type-1 .con, .refresh-loading .g-m--c { width: 16px; height: 16px; border-radius: 50%; -webkit-animation-name: locate-loading; -moz-animation-name: locate-loading; animation-name: locate-loading; -webkit-animation-duration: 1.58s; -moz-animation-duration: 1.58s; animation-duration: 1.58s; -webkit-animation-timing-function: linear; -moz-animation-timing-function: linear; animation-timing-function: linear; -webkit-animation-iteration-count: infinite; -moz-animation-iteration-count: infinite; animation-iteration-count: infinite; border-top: 2px solid #f43939; border-left: 2px solid #df5555; margin: auto; } @keyframes locate-loading { 0% { opacity: 1; -webkit-transform: rotate(0deg); -moz-transform: rotate(0deg); transform: rotate(0deg); } 100% { opacity: 1; -webkit-transform: rotate(360deg); -moz-transform: rotate(360deg); transform: rotate(360deg); } } @-webkit-keyframes locate-loading { 0% { opacity: 1; -webkit-transform: rotate(0deg); -moz-transform: rotate(0deg); transform: rotate(0deg); } 100% { opacity: 1; -webkit-transform: rotate(360deg); -moz-transform: rotate(360deg); transform: rotate(360deg); } } @-moz-keyframes locate-loading { 0% { opacity: 1; -webkit-transform: rotate(0deg); -moz-transform: rotate(0deg); transform: rotate(0deg); } 100% { opacity: 1; -webkit-transform: rotate(360deg); -moz-transform: rotate(360deg); transform: rotate(360deg); } } .refresh-txt { color: #999; text-align: center; font-size: 12px; } /* 上拉載入 */ .more-c { font-size: 12px; } .more-c .con { margin: 0 5px 0 0; } .more-c .type { display: flex; flex-direction: column; align-items: center; justify-content: center; } .type-1:after { content: '載入中...'; display: inline-block }
html
<!-- 不設定高度,在執行滾動時,監聽不到div上有scroll事件 --> <!-- height: 100%;設定高度,不然會監聽不到scroll --> <body style="background-color: #FFFFFF;height: 100%;"> <div class="app_header"></div> <!-- height: 100%;overflow: auto;設定高度,不然會監聽不到scroll --> <div class="warper" style="padding-top: 120px;overflow: auto;width: 100%;height: 100%;"> <!-- 下拉重新整理 --> <div class="refresh-loading" > <div class="g-m--c"></div> <p class="refresh-txt">下拉可重新整理</p> </div> <!-- 下拉重新整理 --> <!-- 資料渲染容器 --> <div id="result" class="scroll"></div> <!-- 資料渲染模板 --> <!-- 上拉載入 --> <div class="more-c"> <div id="loadMore" class="type"> <div class="con"></div> </div> </div> <!-- 上拉載入 --> </div>
JavaScript
var page = 1;//頁面顯示頁碼 var quantity = 10;//每頁顯示總數 var isPullUpLoad = false;//是否為上拉載入 var isPullDownRefresh = true;//下拉重新整理 /** 下拉重新整理/上拉載入 開始 **/ var moveEle = document.getElementsByClassName('warper')[0]; //內容容器,可視區域 var scrollView = document.getElementsByClassName('scroll')[0]; //真正的內容 var refreshEle = document.getElementsByClassName('refresh-loading')[0]; //重新整理的loading var refreshTxtEle = document.getElementsByClassName('refresh-txt')[0]; //重新整理顯示的提示文字 var touch, moved, startY, diff, moveDiff = 60; // 設定一個移動距離 // 可視區域監聽觸控開始 moveEle.addEventListener('touchstart', function (e) { // fyappapi.toastInfo(moveEle.scrollTop); if (moveEle.scrollTop > 0) { //當頁面已經有滾動或者不是置頂的時候,不需要進行下拉重新整理,是頁面正常的滑動 touch = false; return; } touch = true; //觸控開始 moved = false; //還沒有進行下拉重新整理的滑動 startY = e.touches[0].clientY; //記錄當前手指在螢幕上的縱向座標,用於判斷頁面是上滑還是下滑 }, false); // 可視區域監聽移動 moveEle.addEventListener('touchmove', function (e) { if (!touch || !isPullDownRefresh) { return; } var touchesDiff = e.touches[0].clientY - startY; //計算的移動位移 if (touchesDiff < 0) { //說明頁面是向上滑的,不做任何操作 moved = false; return; } moved = true; diff = touchesDiff; var distance = 0; if (diff <= moveDiff) { //moveDiff至少要等於loading的高度 //當滑動小於規定的臨界值時 distance = diff; refreshTxtEle.innerHTML = '下拉可重新整理'; } else { refreshTxtEle.innerHTML = '釋放可重新整理'; //彈性 if (touchesDiff <= (2 * moveDiff)) { distance = moveDiff + 0.5 * (touchesDiff - moveDiff); } else { distance = moveDiff + 0.1 * (touchesDiff - moveDiff) + 0.05 * (touchesDiff - 2 * moveDiff); } } if (distance > 0) { //滑動的距離 css(refreshEle, 0); refreshEle.style.height = distance + 'px'; } generatedCount = 0; //下拉重新整理的時候清空上拉載入更多的次數統計 }, false); // 可視區域監聽觸控完成 moveEle.addEventListener('touchend', function (e) { if (!touch || !moved) { refreshEle.style.height = '0px'; return; } css(refreshEle, 300); isPullDownRefresh = false; if (diff > moveDiff) { refreshTxtEle.innerHTML = '重新整理中'; refreshEle.style.height = moveDiff + 'px'; setTimeout(() => { // fyappapi.toastInfo('下拉重新整理'); //延遲模擬介面呼叫 css(refreshEle, 300); page = 1; quantity = 100; if(type == 0){ // 店鋪 getdata(); }else{ getcangku(); // 倉庫 } refreshEle.style.height = '0px'; setTimeout(() => { isPullDownRefresh = true; //控制在重新整理期間,重複向下拉動,不做任何操作 }, 300); }, 500); } else { isPullDownRefresh = true; refreshEle.style.height = '0px'; } }, false); function css(ele, t) { ele.style.transition = "all " + t + "ms"; ele.style.webkitTransition = "all " + t + "ms"; } //上拉載入 開始 var loadMore = document.getElementById('loadMore'); var className = loadMore.getAttribute('class'); // fyappapi.toastInfo(scrollView.offsetHeight); //上拉載入 監聽scroll 若未設定 moveEle.addEventListener('scroll', function (e) { requestAnimationFrame(function () { //當資料正在載入時,直接返回 if (isPullUpLoad) { return; } var contentHeight = scrollView.offsetHeight; //1500 //滾動的距離,加上可視視窗的高度,因為設定了content的max-height為300px var scrollTop = moveEle.scrollTop + 300; //開始325.5 最後 1124 // alert(scrollTop); // 原這裡減掉30,可能因為佈局不同,我需要減到400才能觸發 if (contentHeight && scrollTop > contentHeight - 400) { //當滾動距離內容底部30px的時候,拉取下一頁資料 //html5提供的classList loadMore.classList.add('type-1'); isPullUpLoad = true; setTimeout(() => { //介面呼叫 loadMore.classList.remove('type-1'); // fyappapi.toastInfo('介面呼叫'); page ++ ; if(type == 0){ // 店鋪 getdata(); }else{ getcangku(); // 倉庫 } }, 300); } }); }, false); /** 下拉重新整理/上拉載入 完 **/ // 介面獲取資料渲染介面 根據 isPullUpLoad 判斷 if (data.status == 1) { var template = $.templates("#theTmpl"); var htmlOutput = template.render(data.result); if (isPullUpLoad != true) { $("#result").html(htmlOutput); } else { isPullUpLoad = false; $("#result").append(htmlOutput); } } else { if (isPullUpLoad == true) { isPullUpLoad = false; page--; fyappapi.toastInfo("沒有更多資料了!"); } else { $("#result").html(`<div style="display: flex;flex-direction: column;justify-content: center;align-items: center;margin-top: 40%;"> <img style="width: 50%;height: 50%;" src="__PUBLIC__/img/nono_data.png" /> <span style="margin-top: 30px;font-size: 20px;color: #666666;">暫無資料</span> </div>`); } }