關於下拉刷新和上啦加載更多的功能,若有不正之處,請指教哈
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
}
}
