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

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

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

瀏覽:145日期: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久久,三上悠亚国产精品一区二区三区
精品一二三区| 久久三级毛片| 日产精品一区二区| 亚洲一区二区三区在线免费| 中文在线а√天堂| 精品欧美日韩精品| 国产欧美啪啪| 日韩高清在线一区| 久久要要av| 国产精品三级| 日韩激情精品| 中文一区一区三区免费在线观 | 亚洲三级网站| 亚洲免费黄色| 黄色亚洲在线| 亚洲一卡久久| 亚洲欧洲一区| 久久国产精品亚洲77777| 亚洲黄色影院| 激情五月综合| 在线一区电影| 香蕉视频亚洲一级| 欧美精品高清| 亚洲电影在线| 亚洲激情中文| 亚洲美洲欧洲综合国产一区| 亚洲综合日本| 免费久久精品视频| 国产手机视频一区二区| 国产亚洲永久域名| 只有精品亚洲| 日韩黄色免费网站| 欧美日韩亚洲一区在线观看| 国产欧美三级| 精品一区二区三区在线观看视频 | sm久久捆绑调教精品一区| 精品视频亚洲| 丝袜美腿诱惑一区二区三区| 91精品国产91久久久久久黑人| 99国产精品免费视频观看| 精品一区毛片| 最新国产精品视频| 97久久精品| 欧美日韩1区2区3区| 国产图片一区| 久久精品网址| 日韩一区二区三区在线免费观看| 尤物tv在线精品| 天堂成人国产精品一区| 亚洲精品在线国产| 日韩avvvv在线播放| 久久只有精品| 色吊丝一区二区| 亚洲欧美日韩高清在线| 视频一区二区三区入口| 欧美日韩一区二区三区四区在线观看 | 久久久男人天堂| 国产专区一区| 欧美精品一线| 视频一区日韩精品| 久久99蜜桃| 日本少妇一区| 最新国产拍偷乱拍精品| 亚洲精选成人| 美女性感视频久久| 久久伦理在线| 蜜臀va亚洲va欧美va天堂| 成人在线视频区| 黑丝一区二区| 91精品啪在线观看国产18| 亚洲激情另类| 欧美亚洲自偷自偷| 日韩免费久久| 婷婷精品在线| 精品黄色一级片| 99日韩精品| 欧美国产日韩电影| 麻豆视频在线观看免费网站黄 | 日本不卡在线视频| 人在线成免费视频| 亚洲永久精品唐人导航网址| 国产精品一区二区av日韩在线| 午夜av不卡| 亚洲啊v在线免费视频| 欧美一区久久久| 四虎在线精品| 精品亚洲美女网站| 青草av.久久免费一区| 精品日韩视频| 国产精品啊啊啊| 午夜性色一区二区三区免费视频| 激情综合亚洲| 国产精品国产一区| 国产精东传媒成人av电影| 日韩在线一区二区| 国产视频一区三区| 蜜桃成人av| 日韩欧美一区二区三区免费观看| 久久字幕精品一区| 国产精品一国产精品k频道56| 综合欧美精品| 蜜乳av另类精品一区二区| 久久要要av| 日韩在线短视频| 在线天堂资源www在线污| 久久久久亚洲精品中文字幕| 国产精品www.| 国产激情精品一区二区三区| 欧美日韩 国产精品| 亚州av一区| 日韩一区免费| 日韩成人午夜精品| 国产日韩一区二区三区在线播放| 色综合视频一区二区三区日韩| 日韩在线一区二区| 视频一区在线视频| 蜜桃av一区二区三区电影| 一本色道精品久久一区二区三区| 欧美影院三区| 亚洲二区视频| 五月天久久久| 先锋亚洲精品| 久色成人在线| 日韩一二三区在线观看| 日韩精品一区二区三区av| 日韩中文字幕一区二区高清99| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲色图国产| 日韩成人精品一区二区三区 | 91九色综合| 国产精品一区二区三区美女| 亚洲精品三级| 69堂免费精品视频在线播放| 欧美日本二区| 精品一区二区三区中文字幕| 国产成人久久精品一区二区三区| 国产一区二区精品久| 精精国产xxxx视频在线播放 | 日韩一区二区久久| 亚洲婷婷丁香| 久久国产视频网| 老司机免费视频一区二区| 开心激情综合| 亚洲美女久久精品| 欧美/亚洲一区| 日韩制服丝袜先锋影音| 奇米亚洲欧美| 成人在线免费观看网站| 久久久精品久久久久久96| 99视频精品免费观看| 亚洲午夜久久| 国产欧美亚洲精品a| 成人午夜在线| 免费观看不卡av| 亚洲乱码视频| 国产精品日韩精品在线播放| 色欧美自拍视频| 九九综合九九| 日韩欧美高清一区二区三区| 欧美aⅴ一区二区三区视频| 日韩大片在线播放| 中日韩男男gay无套| 91麻豆精品激情在线观看最新| 久久三级中文| 亚洲激情社区| 欧美天堂在线| 91亚洲国产| 免费精品视频| 国产精品v亚洲精品v日韩精品| 日韩欧美国产精品综合嫩v| 亚洲女同一区| 国产精品麻豆成人av电影艾秋 | 国产亚洲高清一区| 日韩欧美一区二区三区免费看| 国产精品美女久久久| 国产亚洲观看| 国产一区亚洲| 欧美一级久久| 不卡视频在线| 国产精品久久久久久久久久齐齐 | 99视频精品| 免费日韩成人| 午夜在线视频一区二区区别| 久久亚洲人体| 热久久久久久久| 精品中文字幕一区二区三区| 亚洲免费在线| 国产精品毛片久久| 亚洲精品三级| 99久久婷婷这里只有精品| 91麻豆精品激情在线观看最新| 99久久久久国产精品| 国产午夜精品一区在线观看| 亚洲午夜av| 精品国产一区二区三区噜噜噜| 久久国产88| 久久人人精品| 久久香蕉网站| 日韩国产欧美在线播放| 99久久夜色精品国产亚洲1000部|