日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Javascript節流函數throttle和防抖函數debounce

瀏覽:142日期:2023-10-06 16:23:44

問題的引出

在一些場景往往由于事件頻繁被觸發,因而頻繁地進行DOM操作、資源加載,導致UI停頓甚至瀏覽器崩潰。

在這樣的情況下,我們實際上的需求大多為停止改變大小n毫秒后執行后續處理;而其他事件大多的需求是以一定的頻率執行后續處理。針對這兩種需求就出現了debounce和throttle兩種解決辦法。

1. resize事件

2. mousemove事件

3. touchmove事件

4.scroll事件

throttle 與 debounce

在現在很多的javascript框架中都提供了這兩個函數。例如 jquery中有throttle和debounce插件, underscore.js ,Lodash.js 等都提供了這兩個函數。

原理:

首先我們會想到設置一定的時間范圍delay,每隔delayms 執行不超過一次。

事件處理函數什么時候執行能? 這里有兩個選擇,一是先執行,再間隔delayms來等待;或者是先等待delayms,然后執行事件處理函數。

操作過程中的事件全不管,反正只執行一次事件處理。

相同低,這一次的事件處理可以是先執行一次,然后后面的事件都不管; 或者前面的都不管,最后操作完了再執行一次事件處理。

區別:

1. throttle

如果將水龍頭擰緊直到水是以水滴的形式流出,那你會發現每隔一段時間,就會有一滴水流出。

也就是會說預先設定一個執行周期,當調用動作的時刻大于等于執行周期則執行該動作,然后進入下一個新周期。

2.debounce

如果用手指一直按住一個彈簧,它將不會彈起直到你松手為止。

也就是說當調用動作n毫秒后,才會執行該動作,若在這n毫秒內又調用此動作則將重新計算執行時間。

簡單代碼實現及實驗結果

那么下面我們自己簡單地實現下這兩個函數:

throttle 函數:

window.addEventListener('resize', throttle(callback, 300, {leading:false})); window.addEventListener('resize', callback2); function callback () { console.count('Throttled'); } function callback2 () { console.count('Not Throttled'); } /** * 頻率控制函數, fn執行次數不超過 1 次/delay * @param fn{Function} 傳入的函數 * @param delay{Number} 時間間隔 * @param options{Object} 如果想忽略開始邊界上的調用則傳入 {leading:false}, * 如果想忽略結束邊界上的調用則傳入 {trailing:false}, * @returns {Function} 返回調用函數 */ function throttle(fn,delay,options) { var wait=false; if (!options) options = {}; return function(){ var that = this,args=arguments; if(!wait){ if (!(options.leading === false)){ fn.apply(that,args); } wait=true; setTimeout(function () { if (!(options.trailing === false)){ fn.apply(that,args); } wait=false; },delay); } } }

將以上代碼貼入瀏覽器中運行,可得到:

Javascript節流函數throttle和防抖函數debounce

下面再看debounce函數的情況,

debounce 函數:

window.addEventListener('resize', throttle(callback, 300, {leading:false}));window.addEventListener('resize', callback2);function callback () { console.count('Throttled'); }function callback2 () { console.count('Not Throttled'); }/** * 空閑控制函數, fn僅執行一次 * @param fn{Function} 傳入的函數 * @param delay{Number} 時間間隔 * @param options{Object} 如果想忽略開始邊界上的調用則傳入 {leading:false}, * 如果想忽略結束邊界上的調用則傳入 {trailing:false}, * @returns {Function} 返回調用函數 */function debounce(fn, delay, options) { var timeoutId; if (!options) options = {}; var leadingExc = false; return function() { var that = this, args = arguments; if (!leadingExc&&!(options.leading === false)) { fn.apply(that, args); } leadingExc=true; if (timeoutId) { clearTimeout(timeoutId); } timeoutId = setTimeout(function() { if (!(options.trailing === false)) {fn.apply(that, args); } leadingExc=false; }, delay); }}

將以上代碼貼入瀏覽器中運行,分三次改變窗口大小,可看到,每一次改變窗口的大小都會把開始和結束邊界的事件處理函數各執行一次:

Javascript節流函數throttle和防抖函數debounce

如果是一次性改變窗口大小,會發現開始和結束的邊界各執行一次時間處理函數,請注意與一次性改變窗口大小時 throttle 情況的對比:

Javascript節流函數throttle和防抖函數debounce

underscore.js 的代碼實現

_.throttle函數

/** * 頻率控制函數, fn執行次數不超過 1 次/delay * @param fn{Function} 傳入的函數 * @param delay{Number} 時間間隔 * @param options{Object} 如果想忽略開始邊界上的調用則傳入 {leading:false}, * 如果想忽略結束邊界上的調用則傳入 {trailing:false}, * @returns {Function} 返回調用函數 */_.throttle = function(func, wait, options) { var context, args, result; var timeout = null; var previous = 0; if (!options) options = {}; var later = function() { previous = options.leading === false ? 0 : _.now(); timeout = null; result = func.apply(context, args); if (!timeout) context = args = null; }; return function() { var now = _.now(); if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0 || remaining > wait) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); if (!timeout) context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; };};

_.debounce函數

/** * 空閑控制函數, fn僅執行一次 * @param fn{Function} 傳入的函數 * @param delay{Number} 時間間隔 * @param options{Object} 如果想忽略開始邊界上的調用則傳入 {leading:false}, * 如果想忽略結束邊界上的調用則傳入 {trailing:false}, * @returns {Function} 返回調用函數 */_.debounce = function(func, wait, immediate) { var timeout, args, context, timestamp, result; var later = function() { var last = _.now() - timestamp; if (last < wait && last > 0) { timeout = setTimeout(later, wait - last); } else { timeout = null; if (!immediate) {result = func.apply(context, args);if (!timeout) context = args = null; } } }; return function() { context = this; args = arguments; timestamp = _.now(); var callNow = immediate && !timeout; if (!timeout) timeout = setTimeout(later, wait); if (callNow) { result = func.apply(context, args); context = args = null; } return result; };};

參考的文章

Debounce and Throttle: a visual explanationjQuery throttle / debounce: Sometimes, less is more!underscore.js

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩精品网站| 国产日韩三级| 99香蕉国产精品偷在线观看 | 91久久久久| 国产网站在线| 麻豆精品视频在线观看| 日韩欧美中文在线观看| 亚洲欧美日韩国产一区二区| 久久免费国产| 天堂av在线| 久久精品色播| 欧美a在线观看| 国产欧美日韩在线观看视频| 日本不卡一区二区三区| 美女精品在线观看| 国产色播av在线| 精品免费视频| 欧美极品一区二区三区| 国产精品jk白丝蜜臀av小说| 久久国产日韩欧美精品| 日韩精彩视频在线观看| 婷婷国产精品| 亚洲婷婷免费| 激情婷婷久久| 2023国产精品久久久精品双| 99久久夜色精品国产亚洲1000部| 在线手机中文字幕| 国产中文欧美日韩在线| 精品国产91| 精品中文在线| 久久av免费| 精品欧美日韩精品| 成人在线免费观看网站| 日韩av在线播放网址| 高清不卡一区| 韩国精品主播一区二区在线观看| 欧美成a人免费观看久久| 久久精品国内一区二区三区水蜜桃| 蜜臀国产一区| 亚洲一级特黄| 国产亚洲网站| 午夜精品网站| 亚洲一区二区三区无吗| 亚洲精品一级| 久久国产生活片100| 国产精品magnet| 精品一区不卡| 毛片在线网站| 欧美另类专区| 中文字幕一区二区精品区| 日本午夜精品视频在线观看| 国产精品一页| 精品一区二区三区免费看| 日韩在线观看一区| 日韩欧美二区| 欧美日韩国产免费观看| 亚洲18在线| 国产精品第十页| 欧美少妇精品| 亚洲欧美日韩在线观看a三区| 蜜臀精品久久久久久蜜臀| 一区二区三区四区日韩| 国产精品久久久久av蜜臀| 超碰在线99| 国内精品99| 日韩激情av在线| 久久精品国产一区二区| 蜜臀久久99精品久久一区二区| 九一精品国产| 日本精品在线播放| 国产一区二区三区不卡视频网站| 伊人久久大香线蕉av不卡| 综合精品一区| 精品久久国产一区| 亚洲小说欧美另类婷婷| 免费高清在线一区| 欧美激情网址| 国产在线成人| 青青伊人久久| 国产综合色区在线观看| 亚洲精品美女| 91av亚洲| 视频在线观看一区| 久久字幕精品一区| 国产精品普通话对白| 国产视频网站一区二区三区| 久久久777| 91精品福利观看| 在线观看精品| 免费久久精品视频| 久久av影院| 婷婷久久一区| 麻豆视频观看网址久久| 久久亚洲电影| 精品国产第一福利网站| 伊人久久婷婷| 国产一区二区三区久久| 亚洲无线观看| 欧洲一区二区三区精品| 亚洲精品国模| 99成人超碰| 欧美久久亚洲| 欧洲av一区二区| 久久国产精品免费一区二区三区| 久久天堂成人| 久久精品99国产精品| 韩日一区二区三区| 日本精品国产| 欧美日韩国产综合网| 精品一区二区三区的国产在线观看 | 亚洲激情偷拍| 欧美影院三区| 久久亚洲专区| 欧美99久久| 久久精品高清| 日韩av二区| 国产成人精品一区二区三区视频| 国产精品亚洲片在线播放| 国产亚洲欧美日韩精品一区二区三区 | 99久久九九| 色婷婷久久久| 日韩福利一区| 欧美freesex黑人又粗又大| 日韩成人免费| 日韩在线看片| 欧美成人基地| 欧美天堂视频| 久久精品动漫| 成人av二区| 六月天综合网| 亚洲欧洲国产精品一区| 97精品久久| 欧美1区2区3| 国产精品毛片一区二区在线看| 麻豆视频在线看| 99视频精品视频高清免费| 久久精品高清| 午夜在线视频观看日韩17c| 亚洲精品影视| 欧美精品成人| 在线看片福利| 激情五月综合网| 蜜桃免费网站一区二区三区| 日韩高清在线不卡| 欧美激情三区| 六月婷婷综合| 亚洲成人日韩| 美女尤物久久精品| 88久久精品| 精品理论电影在线| 欧洲亚洲一区二区三区| 久久久久久久久久久妇女| 午夜av一区| 91精品国产自产精品男人的天堂 | 国产一区二区三区国产精品| 日韩欧美视频专区| 99xxxx成人网| 91成人在线| 狠狠躁少妇一区二区三区| 成人av二区| 日本成人在线网站| 成人精品久久| 亚洲主播在线| 国产麻豆精品久久| 国产aⅴ精品一区二区三区久久 | 亚洲深深色噜噜狠狠爱网站| 国产毛片久久久| 日韩成人三级| 蜜臀久久99精品久久久画质超高清 | 中文字幕在线高清| 日韩一区二区免费看| 日韩成人午夜精品| 国产日产一区| 激情黄产视频在线免费观看| 2023国产精品久久久精品双| 日韩av在线免费观看不卡| 精品国产99| 国产精品社区| 久久69成人| 奶水喷射视频一区| 国产一区日韩| 热久久免费视频| 狂野欧美性猛交xxxx| 国产在线成人| 国产精品蜜月aⅴ在线| 精精国产xxxx视频在线野外| 亚洲深夜福利在线观看| 欧美国产中文高清| 午夜日韩福利| 精品日韩一区| 婷婷精品久久久久久久久久不卡| 精品国产一区二区三区噜噜噜| 亚洲欧美久久久| 国产a亚洲精品| 深夜福利一区| 久久国产影院| 国产精品极品在线观看| 黄色亚洲精品| 高清在线一区| 日韩二区三区在线观看|