摘要:當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會清除前一次的定時(shí)器并設(shè)置另一個。然而,如果前一個定時(shí)器尚未執(zhí)行,其實(shí)就是將其替換為一個新的定時(shí)器,然后延遲一定時(shí)間再執(zhí)行。參考文章函數(shù)節(jié)流與函數(shù)防抖函數(shù)節(jié)流和函數(shù)去抖應(yīng)用場景辨析函數(shù)節(jié)流函數(shù)防抖實(shí)現(xiàn)原理分析
前言
事件的觸發(fā)權(quán)很多時(shí)候都屬于用戶,有些情況下會產(chǎn)生問題:
向后臺發(fā)送數(shù)據(jù),用戶頻繁觸發(fā),對服務(wù)器造成壓力
一些瀏覽器事件:window.onresize、window.mousemove等,觸發(fā)的頻率非常高,會造成瀏覽器性能問題
如果你碰到這些問題,那就需要用到函數(shù)節(jié)流和防抖了。
本文首發(fā)地址為GitHub博客,寫文章不易,請多多支持與關(guān)注!
一、函數(shù)節(jié)流(throttle)函數(shù)節(jié)流:一個函數(shù)執(zhí)行一次后,只有大于設(shè)定的執(zhí)行周期后才會執(zhí)行第二次。
有個需要頻繁觸發(fā)函數(shù),出于優(yōu)化性能角度,在規(guī)定時(shí)間內(nèi),只讓函數(shù)觸發(fā)的第一次生效,后面不生效。
其原理是用時(shí)間戳來判斷是否已到回調(diào)該執(zhí)行時(shí)間,記錄上次執(zhí)行的時(shí)間戳,然后每次觸發(fā) scroll 事件執(zhí)行回調(diào),回調(diào)中判斷當(dāng)前時(shí)間戳距離上次執(zhí)行時(shí)間戳的間隔是否已經(jīng)到達(dá) 規(guī)定時(shí)間段,如果是,則執(zhí)行,并更新上次執(zhí)行的時(shí)間戳,如此循環(huán);
html, body { height: 500%; // 讓其出現(xiàn)滾動條 }
function throttle(fn, delay) { // 記錄上一次函數(shù)觸發(fā)的時(shí)間 var lastTime = 0; return function() { // 記錄當(dāng)前函數(shù)觸發(fā)的時(shí)間 var nowTime = Date.now(); if (nowTime - lastTime > delay) { // 修正this指向問題 fn.call(this); // 同步時(shí)間 lastTime = nowTime; } } } document.onscroll = throttle(function() { console.log("scroll事件被觸發(fā)了" + Date.now()) }, 200)
上例中用到了閉包的特性--可以使變量lastTime的值長期保存在內(nèi)存中。
2.函數(shù)節(jié)流的應(yīng)用場景需要間隔一定時(shí)間觸發(fā)回調(diào)來控制函數(shù)調(diào)用頻率:
DOM 元素的拖拽功能實(shí)現(xiàn)(mousemove)
搜索聯(lián)想(keyup)
計(jì)算鼠標(biāo)移動的距離(mousemove)
Canvas 模擬畫板功能(mousemove)
射擊游戲的 mousedown/keydown 事件(單位時(shí)間只能發(fā)射一顆子彈)
監(jiān)聽滾動事件判斷是否到頁面底部自動加載更多:給 scroll 加了 debounce 后,只有用戶停止?jié)L動后,才會判斷是否到了頁面底部;如果是 throttle 的話,只要頁面滾動就會間隔一段時(shí)間判斷一次
二、函數(shù)防抖(debounce)防抖函數(shù):一個需要頻繁觸發(fā)的函數(shù),在規(guī)定時(shí)間內(nèi),只讓最后一次生效,前面的不生效。
1.如何實(shí)現(xiàn)其原理就第一次調(diào)用函數(shù),創(chuàng)建一個定時(shí)器,在指定的時(shí)間間隔之后運(yùn)行代碼。當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會清除前一次的定時(shí)器并設(shè)置另一個。如果前一個定時(shí)器已經(jīng)執(zhí)行過了,這個操作就沒有任何意義。然而,如果前一個定時(shí)器尚未執(zhí)行,其實(shí)就是將其替換為一個新的定時(shí)器,然后延遲一定時(shí)間再執(zhí)行。
上例中也用到了閉包的特性--可以使變量timer的值長期保存在內(nèi)存中。
2.函數(shù)防抖的應(yīng)用場景對于連續(xù)的事件響應(yīng)我們只需要執(zhí)行一次回調(diào):
每次 resize/scroll 觸發(fā)統(tǒng)計(jì)事件
文本輸入的驗(yàn)證(連續(xù)輸入文字后發(fā)送 AJAX 請求進(jìn)行驗(yàn)證,驗(yàn)證一次就好)
三、總結(jié)函數(shù)節(jié)流和函數(shù)去抖的核心其實(shí)就是限制某一個方法被頻繁觸發(fā),而一個方法之所以會被頻繁觸發(fā),大多數(shù)情況下是因?yàn)?DOM 事件的監(jiān)聽回調(diào),而這也是函數(shù)節(jié)流以及防抖多數(shù)情況下的應(yīng)用場景。
參考文章 函數(shù)節(jié)流與函數(shù)防抖 JavaScript 函數(shù)節(jié)流和函數(shù)去抖應(yīng)用場景辨析 函數(shù)節(jié)流、函數(shù)防抖實(shí)現(xiàn)原理分析文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/53372.html
摘要:節(jié)流在指定時(shí)間之內(nèi),讓函數(shù)只觸發(fā)一次。防抖對于一定時(shí)間段的連續(xù)的函數(shù)調(diào)用,只讓其執(zhí)行一次??偨Y(jié)以上只是很簡單的寫了一下節(jié)流和防抖的原理,在里,實(shí)現(xiàn)起來更加復(fù)雜,但是背后的原理核心就是上邊代碼寫的。 概述 在平時(shí)的開發(fā)中,經(jīng)常會聽到兩個差不多很相近的詞。節(jié)流(throttle)和防抖(debounce)。這是兩個類似又有些不同的優(yōu)化方案。 節(jié)流:在指定時(shí)間之內(nèi),讓函數(shù)只觸發(fā)一次。 防...
摘要:當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會清除前一次的定時(shí)器并設(shè)置另一個。然而,如果前一個定時(shí)器尚未執(zhí)行,其實(shí)就是將其替換為一個新的定時(shí)器,然后延遲一定時(shí)間再執(zhí)行。參考文章函數(shù)節(jié)流與函數(shù)防抖函數(shù)節(jié)流和函數(shù)去抖應(yīng)用場景辨析函數(shù)節(jié)流函數(shù)防抖實(shí)現(xiàn)原理分析 前言 事件的觸發(fā)權(quán)很多時(shí)候都屬于用戶,有些情況下會產(chǎn)生問題: 向后臺發(fā)送數(shù)據(jù),用戶頻繁觸發(fā),對服務(wù)器造成壓力 一些瀏覽器事件:window.onresi...
摘要:當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會清除前一次的定時(shí)器并設(shè)置另一個。然而,如果前一個定時(shí)器尚未執(zhí)行,其實(shí)就是將其替換為一個新的定時(shí)器,然后延遲一定時(shí)間再執(zhí)行。參考文章函數(shù)節(jié)流與函數(shù)防抖函數(shù)節(jié)流和函數(shù)去抖應(yīng)用場景辨析函數(shù)節(jié)流函數(shù)防抖實(shí)現(xiàn)原理分析 前言 事件的觸發(fā)權(quán)很多時(shí)候都屬于用戶,有些情況下會產(chǎn)生問題: 向后臺發(fā)送數(shù)據(jù),用戶頻繁觸發(fā),對服務(wù)器造成壓力 一些瀏覽器事件:window.onresi...
摘要:今天和別人聊到函數(shù)的節(jié)流和防抖,發(fā)現(xiàn)自己對這兩個的區(qū)別很是模糊,遂小小實(shí)踐一下,在此記錄,希望對需要的人有所幫助。防抖實(shí)現(xiàn)順利,但是兩個節(jié)流方法的執(zhí)行結(jié)果存在差異。 今天和別人聊到JavaScript函數(shù)的節(jié)流和防抖,發(fā)現(xiàn)自己對這兩個的區(qū)別很是模糊,遂小小實(shí)踐一下,在此記錄,希望對需要的人有所幫助。 節(jié)流 - 頻繁操作,間隔一定時(shí)間去做一件事 舉例說明:假定時(shí)間間隔為 500ms,頻繁...
摘要:文件為函數(shù)要傳入的參數(shù)返回事件處理函數(shù)添加事件監(jiān)聽節(jié)流函數(shù)一般用于事件的情況較多,因?yàn)檫@些事件的觸發(fā)是連續(xù)性的,需要在一個時(shí)間間隔內(nèi)只觸發(fā)一次。 showImg(https://segmentfault.com/img/remote/1460000018998747); 閱讀原文 前言 在前端開發(fā)當(dāng)中我們經(jīng)常會綁定一些事件觸發(fā)的某些程序執(zhí)行,有時(shí)這些事件會連續(xù)觸發(fā),如瀏覽器窗口 s...
閱讀 1031·2021-09-26 09:55
閱讀 3596·2021-09-24 10:30
閱讀 1381·2021-09-08 09:36
閱讀 2563·2021-09-07 09:58
閱讀 613·2019-08-30 15:56
閱讀 779·2019-08-29 18:32
閱讀 3640·2019-08-29 15:13
閱讀 1851·2019-08-29 13:49