關於下拉刷新和上啦加載更多的功能,若有不正之處,請指教哈
css代碼
html, body { height: 100%; overflow: hidden; } * { margin: 0; padding: 0; box-sizing: border-box; } ul { list-style: none; } .wrapper { position: relative; height: 100%; overflow: scroll; } .tab { position: absolute; top: 0; left: 0; right: 0; height: 40px; line-height: 40px; text-align: center; font-size: 14px; color: #000; border-bottom: 1px solid red; background: #fff; z-index: 10; } .list { position: absolute; top: 40px; left: 0; right: 0; background: #fff; z-index: 2 } .item { margin-bottom: 10px; height: 80px; line-height: 80px; padding-left: 20px; border-bottom: 1px solid #ededed; background: #f4f4f4 } .text { position: absolute; left: 0; right: 0; text-align: center; height: 30px; line-height: 30px; color: rgba(0, 0, 0, .5); z-index: 1 } .top-text { top: -30px }
HTML
<div class="wrapper"> <p class="tab">選項卡</p> <ul class="list"> <li class="top-text text">下拉刷新</li> </ul> </div>
JS
const MORE = 'MORE'; const INIT = 'INIT'; let wrapper = document.querySelector('.wrapper'); let list = document.querySelector('.list'); let topItem = document.querySelector('.top-text'); let sTop; // 觸發touch事件時的距離選項卡底部的距離 let mTop; // touchmove時距離選項卡底部的位置 let eTop; // 記錄touchend時的位置 // let isRefresh = false; let startOffsetTop = 40;// 距離頂部的距離,tab的高度 let wScrollTop; // wrapper 節點是否滾動 let maxTop = 100; // 最多下拉100px let minTop = 20; // 最小下拉20px,小於20px時不處理 window.onload = function(){ // let bottomItem = document.querySelector('.bottom-text'); loadData(INIT, 10); list.addEventListener('touchstart', function (e) { sTop = e.touches[0].pageY - startOffsetTop; }); list.addEventListener('touchmove', function (e) { // 只有當列表處於頂部的時候下拉刷新才有用 wScrollTop = wrapper.scrollTop; mTop = e.touches[0].pageY - startOffsetTop; if(wScrollTop <= 0){ // 下拉過程中設置list的位置 let mOffsetTop = mTop - sTop + startOffsetTop + 'px'; if (mTop > sTop) { if (mTop - sTop < 30) { topItem.innerHTML = '下拉刷新'; } else { topItem.innerHTML = '釋放刷新'; } if ((mTop - sTop) <= maxTop) { list.style.top = mOffsetTop; } else { list.style.top = maxTop + startOffsetTop + 'px' } } } // 此處判斷是否到底部會存在滾動到底部后第一次touch不會加載數據的情況,所以使用onscroll事件 // if(isToBottom()){ // loadData(MORE, 3) // } }); list.addEventListener('touchend', function (e) { eTop = list.offsetTop; if (eTop >= (minTop + startOffsetTop)) { loadData(MORE, 3); topItem.innerHTML = '正在加載'; setTimeout(function () { resize() }, 1000) } else { resize() } }); wrapper.onscroll = function(){ if(isToBottom()){ loadData(MORE, 3) } }; }; function loadData(str, n) { let more = document.querySelector('.bottom-text'); setTimeout(function () { for (let i = 0; i < n; i++) { let node = document.createElement('li'); if(str === INIT){ node.innerHTML = i; }else if(str === MORE) { node.innerHTML = '刷新的數據' + i; } node.className = 'item'; list.insertBefore(node, more); } }, 2000) } function resize() { let time = setInterval(function () { if (list.offsetTop <= startOffsetTop) { clearInterval(time); topItem.innerHTML = '下拉加載'; } else { list.style.top = list.offsetTop - 1 + 'px'; topItem.innerHTML = '加載完成'; } }, 5) } // 判斷是否滾動到底部 function isToBottom(){ // 這里在計算wrapper.scrollTop的時候存在一定問題 if(wrapper.scrollHeight - wrapper.scrollTop - document.body.clientHeight < 5){ console.log('底部'); return true } }