vue 中用js判斷滾動條是否到了底部

在網(wǎng)頁中,我們會遇到很多在滾動條到底部的時候有數(shù)據(jù)正在加載的事件汪榔,那么怎樣用vue去實現(xiàn)這樣的內(nèi)容呢赦拘?本篇只給出一個雛形,結(jié)合vue的生命周期用純javascript寫的一個監(jiān)聽函數(shù)垛贤,后續(xù)操作數(shù)據(jù)庫的部分暫且不議焰坪。

1、怎樣用純js判斷滾動條是否到底部聘惦?

先了解幾個關鍵詞:

(1)滾動條到頂部的位置:scrollTop

(2)當前窗口內(nèi)容可視區(qū):windowHeight

(3)滾動條內(nèi)容的總高度:scrollHeight

觸發(fā)監(jiān)聽的函數(shù)是:

window.onscroll = function(){...}

判斷到底部的等式: scrollTop+windowHeight=scrollHeight;

2某饰、主要函數(shù)代碼

created(){
window.onscroll = function(){
    //變量scrollTop是滾動條滾動時,距離頂部的距離
    var scrollTop = document.documentElement.scrollTop||document.body.scrollTop;
    //變量windowHeight是可視區(qū)的高度
    var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
    //變量scrollHeight是滾動條的總高度
    var scrollHeight = document.documentElement.scrollHeight||document.body.scrollHeight;
           //滾動條到底部的條件
           if(scrollTop+windowHeight==scrollHeight){
            //寫后臺加載數(shù)據(jù)的函數(shù)
        console.log("距頂部"+scrollTop+"可視區(qū)高度"+windowHeight+"滾動條總高度"+scrollHeight);
          }   
    }

}

函數(shù)節(jié)流和函數(shù)防抖

原文鏈接:justclear.github.io

什么是函數(shù)節(jié)流與函數(shù)防抖

舉個栗子,我們知道目前的一種說法是當 1 秒內(nèi)連續(xù)播放 24 張以上的圖片時黔漂,在人眼的視覺中就會形成一個連貫的動畫诫尽,所以在電影的播放(以前是,現(xiàn)在不知道)中基本是以每秒 24 張的速度播放的炬守,為什么不 100 張或更多是因為 24 張就可以滿足人類視覺需求的時候牧嫉,100 張就會顯得很浪費資源。再舉個栗子减途,假設電梯一次只能載一人的話酣藻,10 個人要上樓的話電梯就得走 10 次,是一種浪費資源的行為鳍置;而實際生活正顯然不是這樣的辽剧,當電梯里有人準備上樓的時候如果外面又有人按電梯的話,電梯會再次打開直到滿載位置税产,從電梯的角度來說怕轿,這時一種節(jié)約資源的行為(相對于一次只能載一個人)。

  • 函數(shù)節(jié)流: 指定時間間隔內(nèi)只會執(zhí)行一次任務砖第;
  • 函數(shù)防抖: 任務頻繁觸發(fā)的情況下撤卢,只有任務觸發(fā)的間隔超過指定間隔的時候,任務才會執(zhí)行梧兼。

函數(shù)節(jié)流(throttle)

這里以判斷頁面是否滾動到底部為例,普通的做法就是監(jiān)聽 window 對象的 scroll 事件智听,然后再函數(shù)體中寫入判斷是否滾動到底部的邏輯:

$(window).on('scroll', function () {
    // 判斷是否滾動到底部的邏輯
    let pageHeight = $('body').height(),
        scrollTop = $(window).scrollTop(),
        winHeight = $(window).height(),
        thresold = pageHeight - scrollTop - winHeight;
    if (thresold > -100 && thresold <= 20) {
        console.log('end');
    }
});

throttle

這樣做的一個缺點就是比較消耗性能羽杰,因為當在滾動的時候,瀏覽器會無時不刻地在計算判斷是否滾動到底部的邏輯到推,而在實際的場景中是不需要這么做的考赛,在實際場景中可能是這樣的:在滾動過程中,每隔一段時間在去計算這個判斷邏輯莉测。而函數(shù)節(jié)流所做的工作就是每隔一段時間去執(zhí)行一次原本需要無時不刻地在執(zhí)行的函數(shù)颜骤,所以在滾動事件中引入函數(shù)的節(jié)流是一個非常好的實踐:

$(window).on('scroll', throttle(function () {
    // 判斷是否滾動到底部的邏輯
    let pageHeight = $('body').height(),
        scrollTop = $(window).scrollTop(),
        winHeight = $(window).height(),
        thresold = pageHeight - scrollTop - winHeight;
    if (thresold > -100 && thresold <= 20) {
        console.log('end');
    }
}));

throttle

加上函數(shù)節(jié)流之后,當頁面再滾動的時候捣卤,每隔 300ms 才會去執(zhí)行一次判斷邏輯忍抽。

簡單來說,函數(shù)的節(jié)流就是通過閉包保存一個標記(canRun = true)董朝,在函數(shù)的開頭判斷這個標記是否為 true鸠项,如果為 true 的話就繼續(xù)執(zhí)行函數(shù),否則則 return 掉子姜,判斷完標記后立即把這個標記設為 false祟绊,然后把外部傳入的函數(shù)的執(zhí)行包在一個 setTimeout 中,最后在 setTimeout執(zhí)行完畢后再把標記設置為 true(這里很關鍵),表示可以執(zhí)行下一次的循環(huán)了牧抽。當 setTimeout 還未執(zhí)行的時候嘉熊,canRun 這個標記始終為 false,在開頭的判斷中被 return 掉扬舒。

function throttle(fn, interval = 300) {
    let canRun = true;
    return function () {
        if (!canRun) return;
        canRun = false;
        setTimeout(() => {
            fn.apply(this, arguments);
            canRun = true;
        }, interval);
    };
}

函數(shù)防抖(debounce)

這里以用戶注冊時驗證用戶名是否被占用為例记舆,如今很多網(wǎng)站為了提高用戶體驗,不會再輸入框失去焦點的時候再去判斷用戶名是否被占用呼巴,而是在輸入的時候就在判斷這個用戶名是否已被注冊:

$('input.user-name').on('input', function () {
    $.ajax({
        url: `https://just.com/check`,
        method: 'post',
        data: {
            username: $(this).val(),
        },
        success(data) {
            if (data.isRegistered) {
                $('.tips').text('該用戶名已被注冊泽腮!');
            } else {
                $('.tips').text('恭喜!該用戶名還未被注冊衣赶!');
            }
        },
        error(error) {
            console.log(error);
        },
    });
});

throttle

很明顯诊赊,這樣的做法不好的是當用戶輸入第一個字符的時候,就開始請求判斷了府瞄,不僅對服務器的壓力增大了碧磅,對用戶體驗也未必比原來的好。而理想的做法應該是這樣的遵馆,當用戶輸入第一個字符后的一段時間內(nèi)如果還有字符輸入的話鲸郊,那就暫時不去請求判斷用戶名是否被占用。在這里引入函數(shù)防抖就能很好地解決這個問題:

$('input.user-name').on('input', debounce(function () {
    $.ajax({
        url: `https://just.com/check`,
        method: 'post',
        data: {
            username: $(this).val(),
        },
        success(data) {
            if (data.isRegistered) {
                $('.tips').text('該用戶名已被注冊货邓!');
            } else {
                $('.tips').text('恭喜秆撮!該用戶名還未被注冊!');
            }
        },
        error(error) {
            console.log(error);
        },
    });
}));

throttle

其實函數(shù)防抖的原理也非常地簡單换况,通過閉包保存一個標記來保存 setTimeout 返回的值职辨,每當用戶輸入的時候把前一個 setTimeout clear 掉,然后又創(chuàng)建一個新的 setTimeout戈二,這樣就能保證輸入字符后的 interval 間隔內(nèi)如果還有字符輸入的話舒裤,就不會執(zhí)行 fn 函數(shù)了。

function debounce(fn, interval = 300) {
    let timeout = null;
    return function () {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            fn.apply(this, arguments);
        }, interval);
    };
}

總結(jié)

其實函數(shù)節(jié)流與函數(shù)防抖的原理非常簡單觉吭,巧妙地使用 setTimeout 來存放待執(zhí)行的函數(shù)腾供,這樣可以很方便的利用 clearTimeout 在合適的時機來清除待執(zhí)行的函數(shù)。

使用函數(shù)節(jié)流與函數(shù)防抖的目的鲜滩,在開頭的栗子中應該也能看得出來伴鳖,就是為了節(jié)約計算機資源。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绒北,一起剝皮案震驚了整個濱河市黎侈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闷游,老刑警劉巖峻汉,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贴汪,死亡現(xiàn)場離奇詭異,居然都是意外死亡休吠,警方通過查閱死者的電腦和手機扳埂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瘤礁,“玉大人阳懂,你說我怎么就攤上這事」袼迹” “怎么了岩调?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赡盘。 經(jīng)常有香客問我号枕,道長,這世上最難降的妖魔是什么陨享? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任葱淳,我火速辦了婚禮,結(jié)果婚禮上抛姑,老公的妹妹穿的比我還像新娘赞厕。我一直安慰自己,他們只是感情好定硝,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布皿桑。 她就那樣靜靜地躺著,像睡著了一般喷斋。 火紅的嫁衣襯著肌膚如雪唁毒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天星爪,我揣著相機與錄音,去河邊找鬼粉私。 笑死顽腾,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的诺核。 我是一名探鬼主播抄肖,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼窖杀!你這毒婦竟也來了漓摩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤入客,失蹤者是張志新(化名)和其女友劉穎管毙,沒想到半個月后腿椎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡夭咬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年啃炸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卓舵。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡南用,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出掏湾,到底是詐尸還是另有隱情裹虫,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布融击,位于F島的核電站筑公,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏砚嘴。R本人自食惡果不足惜十酣,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望际长。 院中可真熱鬧耸采,春花似錦、人聲如沸工育。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽如绸。三九已至嘱朽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間怔接,已是汗流浹背搪泳。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扼脐,地道東北人岸军。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像瓦侮,于是被迫代替她去往敵國和親艰赞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容