上拉加載下拉刷新瞭解下

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

image

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

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

.header{    
    width: 100%;    
    height: 1rem;這裏的高度應該與刷新文字同樣高    
    position: fixed;    
    z-index: 100;
}

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

  • 監聽事件
  • 位置計算
  • 控制界面變化
  • 數據更新包

我一個一個進行分析,而後帶大家入坑。java

image

監聽事件,這塊簡單,直接貼代碼
//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);//具體的函數,咱們直接在位置計算中看
位置計算 咱們分下拉刷新,上拉加載兩塊計算,分析可得

下拉刷新的邏輯 = 當前頁面的首項在屏幕中且容器向下滑動的距離大於必定值 上拉加載的邏輯 = 當前頁面已滑動到底部 好,咱們直接看具體的實現邏輯代碼git

//代碼中包含界面變化和數據更新,仔細看哦
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;    
}

核心代碼就這些了,撒花完結,優化什麼的,大家本身看着來咯,大佬別打我,效果圖來了嘛

image

我就是效果圖

image

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

相關文章
相關標籤/搜索