效果

css
html,body{
height:100%; // 其他界面未設置html 無法監聽scroll
}
/* 下拉刷新 */
.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>`);
}
}
道路還是很遙遠 很感恩發布共享的大佬們,我花了三天時間才解決各種問題