移動端滾動的橡皮筋問題

在開發的時候遇到了移動端滾動問題,在網上找了不少辦法都不行,因而本身試了下面這個方法可行。發出來但願能幫助更多的同窗,你們有更好的方法也歡迎在下面分享出來~函數

這裏面涉及到函數節流的知識,詳見JavaScript 節流函數 Throttle 詳解.net

  • 問題描述:頁面中有一個排行榜須要滾動,整個頁面不容許滾動。可是排行榜(class=list)滾動到最上面和最下面,繼續滾動,會致使整個頁面下拉上拉(頁面設置overflow:hidden和fixed也沒法解決)
    分析:和事件冒泡無關,是移動端滾動的橡皮筋效果
  • 解決方法:
    • 在body上監聽touchmove事件
      1. 若target不在排行榜裏(target若既不是list也不是list的子元素),則阻止默認事件
      2. 若target在排行榜裏
        (如下判斷須要進行函數節流,不然會很卡)
        1. 在list滾動到最上方時,阻止繼續向下滾動事件;
        2. 在list滾動到最下方時,阻止繼續向上滾動事件
    • 注意:不能夠在list上的touchmove事件上禁止冒泡,不然下面的設置不生效
  • 最終代碼:
var startY, endY; // 記錄滑動的開始Y座標和當前Y座標
var timer = null;
var previous = null;
var atleast = 10;

$('body').on('touchstart',function(e){
    startY = e.originalEvent.changedTouches[0].pageY;
});

// 禁用手機默認的觸屏滾動行爲
$('body').on('touchmove', function (e) {
    // 若target不在排行榜裏
    if(!$(e.target).is($('.list')) && !$(e.target).parents('.list').length > 0){
        e.preventDefault();
    }

    // 若target在排行榜裏
    else{
        // 函數節流
        var now = +new Date();
        if(!previous){
            checkScroll(e);
            previous = now;
        }
        if (now - previous > atleast){
            checkScroll(e);
            // 重置上一次開始時間爲本次結束時間
            previous = now;
        }
        else{
            clearTimeout(timer);

            timer = setTimeout(function(){
                checkScroll(e);
            },200);
        }
    }
});

function checkScroll(e){
    console.log("check");

    endY = e.originalEvent.changedTouches[0].pageY;
    // 若已經移到頁面最上方,則不容許再向下滑動
    if($('.list').scrollTop() == 0 && endY > startY){
        e.preventDefault();
    }
    // 若已經移到頁面最下方,則不容許再向上滑動
    if($('.list').scrollTop() + $('.list').height() == $('.list')[0].scrollHeight && endY < startY){
        e.preventDefault();
    }
}
相關文章
相關標籤/搜索