再學(xué)JS--事件節(jié)流

節(jié)流

節(jié)流:如果你持續(xù)觸發(fā)事件,每隔一段時間缕溉,只執(zhí)行一次事件

關(guān)于節(jié)流的實現(xiàn)待牵,有兩種主流的實現(xiàn)方式,一種是使用時間戳的方式唧瘾,一種是設(shè)置定時器

使用時間戳

實現(xiàn)思路為:當觸發(fā)條件的時候措译,我們?nèi)〕霎斍暗臅r間戳,然后減去之前的時間戳(初始化為0)饰序,如果大于設(shè)定的時間周期领虹,就執(zhí)行函數(shù),然后更新時間戳為當前的時間戳求豫,如果小于塌衰,則不執(zhí)行

function throttle(func, wait) {
    var context, args
    var previous = 0

    return function() {
        var now = +new Date()
        context = this
        args = arguments

        if(now - previous > wait) {
            func.apply(context, args)
            previous = now
        }
    }
}

使用定時器

實現(xiàn)思路為:當觸發(fā)事件的時候,我們設(shè)置一個定時器蝠嘉,再次觸發(fā)事件的時候最疆,如果定時器存在,就不執(zhí)行蚤告,直到定時器執(zhí)行努酸,然后執(zhí)行函數(shù),清空定時器杜恰,再設(shè)置下一個定時器

function throttle(func, wait) {
    var timeout
    var context, args

    return function() {
        context = this
        args = arguments
        if(!timeout) {
            timeout = setTimeout(function() {
                timeout = null
                func.apply(context, args)
            }, wait)
        }
    }
}

比較兩種方法:

  1. 第一種事件會立即執(zhí)行蚊逢,第二種事件會在n秒后第一次執(zhí)行
  2. 第一種事件停止觸發(fā)后沒有辦法再執(zhí)行事件,第二種事件停止觸發(fā)后依然會再執(zhí)行一次事件

雙劍合璧

鼠標移入能立即執(zhí)行箫章,停止觸發(fā)的時候還能再執(zhí)行一次

function throttle(func, wait) {
    var timeout, context, args, reslut
    var previous = 0

    var later = function() {
        previous = +new Date()
        timeout = null
        func.apply(context, args)
    }

    var throttled = function() {
        var now = +new Date()
        // 下次觸發(fā)func剩余時間
        var remaining = wait - (now - previous)
        context = this
        args = arguments
        // 如果沒有剩余時間了或者你改了系統(tǒng)時間
        if(remaining <=0 || remaining > wait) {
            if(timeout) {
                clearTimeout(timeout)
                timeout = null
            }
            previous = now
            func.apply(context, args)
        } else if(!timeout) {
            timeout = setTimeout(later, remaining)
        }
    }

    return throttled
}

優(yōu)化

我們可增加一個參數(shù)options來約定:

  1. leading:false表示禁用第一次執(zhí)行
  2. trailing:false表示禁用停止觸發(fā)的回調(diào)
function throttle(func, wait, options) {
    var timeout, context, args, reslut
    var previous = 0
    if(!options) options = {}

    var later = function() {
        previous = options.leading === false ? 0 : new Date().getTime()
        timeout = null
        func.apply(context, args)
        if(!timeout) context = args = null
    }

    var throttled = function() {
        var now = new Date().getTime()
        if(!previous && options.leading === false) previous = now
        // 下次觸發(fā)func剩余時間
        var remaining = wait - (now - previous)
        context = this
        args = arguments
        // 如果沒有剩余時間了或者你改了系統(tǒng)時間
        if(remaining <=0 || remaining > wait) {
            if(timeout) {
                clearTimeout(timeout)
                timeout = null
            }
            previous = now
            func.apply(context, args)
            if(!timeout) context = args = null
        } else if(!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining)
        }
    }

    // 取消功能
    throttled.cancel = function() {
        clearTimeout(timeout)
        previous = 0
        timeout = null
    }

    return throttled
}

注意

如果同時設(shè)置 leading:falsetrailing:false,比如當你鼠標移出的時候镜会,因為trailing設(shè)置為false檬寂,停止觸發(fā)的時候不會設(shè)置定時器,所以只要再過了設(shè)置的時間戳表,再移入的話桶至,就會立即執(zhí)行,就違反了leading:false匾旭,所以throttle只有三種用法:

throttle(func, 1000)
throttle(func, 1000, {leading:false})
throttle(func, 1000, {trailing:false})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末镣屹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子价涝,更是在濱河造成了極大的恐慌女蜈,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異伪窖,居然都是意外死亡逸寓,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門覆山,熙熙樓的掌柜王于貴愁眉苦臉地迎上來竹伸,“玉大人,你說我怎么就攤上這事簇宽⊙ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵魏割,是天一觀的道長譬嚣。 經(jīng)常有香客問我,道長见妒,這世上最難降的妖魔是什么孤荣? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮须揣,結(jié)果婚禮上盐股,老公的妹妹穿的比我還像新娘。我一直安慰自己耻卡,他們只是感情好疯汁,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著卵酪,像睡著了一般幌蚊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上溃卡,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天溢豆,我揣著相機與錄音,去河邊找鬼瘸羡。 笑死漩仙,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的犹赖。 我是一名探鬼主播队他,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼峻村!你這毒婦竟也來了麸折?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤粘昨,失蹤者是張志新(化名)和其女友劉穎垢啼,沒想到半個月后窜锯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡膊夹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年衬浑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片放刨。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡工秩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出进统,到底是詐尸還是另有隱情助币,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布螟碎,位于F島的核電站眉菱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏掉分。R本人自食惡果不足惜俭缓,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望酥郭。 院中可真熱鬧华坦,春花似錦、人聲如沸不从。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽椿息。三九已至歹袁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間寝优,已是汗流浹背条舔。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留乏矾,地道東北人孟抗。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像妻熊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子仑最,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354