上拉載入下拉重新整理瞭解下

信心發表於2018-09-06

上拉載入下拉重新整理瞭解下

老樣子,我們先,哦不,今天我們直接上思路,沒有效果圖,真的沒有

上拉載入下拉重新整理瞭解下

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

1.介面上,只分成簡單的兩塊,一塊是上方的重新整理文字,一塊是下方的內容,然後將上方提示內容隱藏在螢幕之外,一般由兩種方式,一種是上面遮一層,另一種是marginTop:負值將其弄出螢幕外,這裡我採用的是第一種,程式碼也很簡單,就隨便貼一下

.header{
    width100%;
    height1rem;這裡的高度應該與重新整理文字一樣高
    position: fixed;
    z-index100;
}
複製程式碼

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;
    }
}
複製程式碼

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

上拉載入下拉重新整理瞭解下

我就是效果圖


這是我的github,歡迎大佬們猛戳,不定時更新

相關文章