1. 程式人生 > >上拉加載 下拉刷新

上拉加載 下拉刷新

adt 超出 his 功能 恢復 可能 gin 添加 body

作者:信心

https://juejin.im/post/5b9091e7e51d450e70423161

我們依舊從界面及邏輯兩塊進行分析

1.界面上,只分成簡單的兩塊,一塊是上方的刷新文字,一塊是下方的內容,然後將上方提示內容隱藏在屏幕之外,一般由兩種方式,一種是上面遮一層,另一種是marginTop:負值將其弄出屏幕外,這裏我采用的是第一種,代碼也很簡單,就隨便貼一下。

.header{

width: 100%;

height: 1rem;這裏的高度應該與刷新文字一樣高

position: fixed;

z-index: 100;

}

2. 功能實現的重頭戲是在邏輯上,主要分成下面幾個部分

  • 監聽事件

  • 位置計算

  • 控制界面變化

  • 數據更新包

我一個一個進行分析,然後帶你們入坑。

監聽事件,這塊簡單,直接貼代碼

//el為下拉的整個節點

// 這裏為添加監聽

this.el.addEventListener(‘touchstart‘, this.refreshTouchStart);

this.el.addEventListener(‘touchmove‘, this.refreshTouchMove);

this.el.addEventListener(‘touchend‘, this.refreshTouchEnd);

//記住在不用的時候要移除監聽哦

this.el.removeEventListener(‘touchstart‘, this.refreshTouchStart);

this.el.removeEventListener(‘touchmove‘, this.refreshTouchMovee);

this.el.removeEventListener(‘touchend‘, this.refreshTouchEnd);

//具體的函數,我們直接在位置計算中看

位置計算 我們分下拉刷新,上拉加載兩塊計算,分析可得

下拉刷新的邏輯 = 當前頁面的首項在屏幕中且容器向下滑動的距離大於一定值

上拉加載的邏輯 = 當前頁面已滑動到底部

好,我們直接看具體的實現邏輯代碼

//代碼中包含界面變化和數據更新,仔細看哦

refreshTouchStart(e) {

let touch = e.changedTouches[0];

this.tipText = ‘下拉刷新‘;

//下拉提示文字

this.startY = touch.clientY;//獲得當前按下點的縱坐標

}

refreshTouchMove(e) {

this.$store.commit(‘bottomShowFalse‘);//與本邏輯無關,滑動時隱藏底部作用

let touch = e.changedTouches[0];

let _move = touch.clientY - this.startY;//獲得滑動的距離

this.bottomFlag = $(‘.present-box‘).offset().top + $(‘.present-box‘).height() - document.body.clientHeight<= 40;//滑動到底部標識

if ($(‘.present-box‘).offset().top >= this.headerHeight) {

//內容主體超出了一個頭部的距離

if (_move > 0 && _move < 1000) {

//滑動距離>0代表下拉//<1000是為了防止神人無限拉阿拉

this.el.style.marginTop = _move + ‘px‘;//根據拉的距離,實現界面上的變化(界面變化)

this.moveDistance = touch.clientY - this.startY;//記錄滑動的距離,在松手後讓他滑啊滑滑回去

if (_move > 50) {//拉到一定程度再下拉刷新,防止誤操作

this.tipText = ‘松開即可刷新‘//上面有了

}

}

}

},

refreshTouchEnd() {

this.$store.commit(‘bottomShowTrue‘);//松開後底部就biu的出現啦

if (this.bottomFlag) {//若符合上拉加載的條件,則直接進行數據更新

this.$emit(‘loadBottom‘);

}

let that = this;

if (this.moveDistance > 50) {

//拉了一定距離才觸發加載動作

this.tipText = ‘數據加載中...‘;

let timer = setInterval(function () {

that.el.style.marginTop = that.el.style.marginTop.split(‘px‘)[0] - 5 + ‘px‘;//如果拉的很長,一次性彈回去影響用戶體驗,所以先讓他彈到50的高度,然後再進行數據更新

if (Number(that.el.style.marginTop.split(‘px‘)[0]) <= 50) {//小於50後就不進行界面變化了,先進行數據更新再變化

clearInterval(timer);

new Promise((resolve, reject) => {

that.$emit(‘loadTop‘, resolve, reject);//通知父控件,下拉刷新條件滿足了,你更新吧

}).then(() => {

that.resetBox();

}).catch(() => {

that.resetBox();//界面恢復(也就是彈回去啦)

});

}

}, 1);//通過一個promise,讓數據更新結束後再進行界面變化。也可以采用其他的方式,如async await方式

} else {

this.resetBox();

}

}

resetBox() {

let that = this;

//使用定時器的方式,biubiubiu的實現滑動界面刷新的效果。

if (this.moveDistance > 0) {

let timer = setInterval(function () {

that.el.style.marginTop = that.el.style.marginTop.split(‘px‘)[0] - 1 + ‘px‘;

if (Number(that.el.style.marginTop.split(‘px‘)[0]) <= 0) clearInterval(timer);//這裏很重要,不刪除,可能看到奇奇怪怪的東西哦

}, 1)

}

this.moveDistance = 0;

}

核心代碼就這些了,撒花完結,優化什麽的,你們自己看著來咯,大佬別打我,效果圖來了嘛

技術分享圖片

上拉加載 下拉刷新