前端常用算法(一):防抖+節流

目錄

第一章 防抖

1.1 防抖(debounce)簡介

1.2 應用場景

1.3 實現思路

1.4 手撕防抖代碼

第二章 節流

2.1 節流(throttle)簡介

2.2?應用場景

2.3?實現思路

2.4 手撕節流代碼(方法:時間戳和計時器)

2.5 時間戳與計時器實現的區別

第三章 總結


第一章 防抖

1.1 防抖(debounce)簡介

  • 場景:用戶在一段時間頻繁點擊執行某個函數/事件,那么在這段時間,用戶點擊一次,計時器重新計時當在這段時間內用戶沒有觸發該函數/事件時,該函數/事件會在這段時間結束時執行。
  • 應用示例理解:回城被打斷,玩家殘血準備回城,需要3s回城成功,但是在這個3s的過程中,玩家又重新點擊了回城,導致3s回城重新計算,再等3s。

1.2 應用場景

  • 登錄、發短信、發送post請求等按鈕/事件避免用戶點擊太快,以致于發送了多次請求,需要防抖,最后一次發送請求即可;
  • 調整瀏覽器窗口大小時,resize 次數過于頻繁,造成計算過多,此時需要一次到位,就用到了防抖;
  • input輸入框獲取到value值不需要輸入一個字符就獲取一次,可以使用防抖,讓其輸入結束之后再獲取其值
  • 文本編輯器實時保存,當無任何更改操作一秒后進行保存。
  • ……

1.3 實現思路

?

1.4 手撕防抖代碼

function debounce(func,delay) {// 定義一個定時器timerlet timer = nullreturn function() {const that = thisconst args = arguments// 防抖核心:每次觸發事件計時器都會重新計時clearTimeout(timer)timer = setTimeout(()=>{func.apply(that,args)},delay)}
}
  • 例子:

未調用防抖函數時:用戶每在input輸入/刪除一個值,都會輸出一個值;

    <input type="text" id="input"><script>let inputDom = document.getElementById('input')//獲取輸入框的輸入內容inputDom.oninput = function(){console.log('this.value',this.value)}</script>

?

?

調用防抖函數后:用戶在input輸入/刪除一個值delay之后才,會輸出一個值

    let inputDom = document.getElementById('input')//func 是執行函數,delay 是事件執行的延遲時間,毫秒function debounce(func,delay) {// 定義一個定時器timerlet timer = nullreturn function() {const that = thisconst args = arguments// 防抖核心:每次觸發事件計時器都會重新計時clearTimeout(timer)timer = setTimeout(()=>{func.apply(that,args)},delay)}}function handler() {console.log('this.value',this.value)}inputDom.addEventListener('input', debounce(handler, 1000))

第二章 節流

2.1 節流(throttle)簡介

  • 場景:用戶在一段時間頻繁點擊執行某個函數/事件,那么在這段時間,用戶點擊一次/多次(調用事件),都不會影響計時器執行,并且該函數/事件只執行一次。
  • 應用示例理解:技能冷卻中,玩家在某種情況下使用了閃現這個技能,但是這個技能的冷卻時間是120s,在這段時間里,玩家遇到危險,想要再使用閃現這個技能,頻繁的點擊它,但是并沒用,閃現不會執行,計時器依然還在倒計時,等到120s倒計時為0才能再使用一次閃現的技能。

2.2?應用場景

  • 窗口調整
  • 頁面滾動
  • 搶購和瘋狂點擊
  • 懶加載獲取滾動條的位置
  • 鼠標連續不斷地觸發某事件(如點擊),只在規定時間內觸發一次
  • ……

2.3?實現思路

2.4 手撕節流代碼(方法:時間戳和計時器)

// ---------------------節流1:使用時間戳---------------------
//func 是事件處理程序,delay 是事件執行的延遲時間,單位:毫秒
function throttle (func, delay) {//定義初始時間(開始觸發事件的時間)let start = 0;return function () {const that = thisconst args = arguments// 獲取當前時間戳let cur =Date.now()// 時間間隔大于延遲時間則進入if (cur - start >= delay) {//執行事件處理程序func.apply(that, args);//更新初始時間start = cur}}
}
// ---------------------節流2:使用定時器---------------------
//func 是事件處理程序,delay 是事件執行的延遲時間,單位:毫秒
function throttle(func, delay){// 自定義一個定時器var timer = null;return function(){var that = this;var args = arguments// timer為null表示可以發送請求了,否則還在請求中,不執行事件if(!timer){timer = setTimeout(function(){//執行事件處理程序func.call(that, args)//事件執行完后把定時器清除掉,下次觸發事件的時候再設置timer = null;}, delay)}  }
}
  • ?例子:

未調用節流函數時,每點擊一次按鈕,都會執行一次函數調用:

<button id="button1">發送了節流請求</button>
const button1Dom = document.getElementById('button1')
button1Dom.addEventListener('click',function(){console.log("節流:我發送了消息")
})

?使用節流函數之后,頻繁的點擊發送請求,它會在計時器結束之后再發,這段時間內點擊發送一次請求之后,不會再發送請求:

const button1Dom = document.getElementById('button1')
// ---------------------節流1:使用時間戳---------------------
//func 是事件處理程序,delay 是事件執行的延遲時間,單位:毫秒
function throttle (func, delay) {//定義初始時間(開始觸發事件的時間)let start = 0;return function () {const that = thisconst args = arguments// 獲取當前時間戳let cur =Date.now()// 時間間隔大于延遲時間則進入if (cur - start >= delay) {//執行事件處理程序func.apply(that, args);//更新初始時間start = cur}}
}
// ---------------------節流2:使用定時器---------------------
//func 是事件處理程序,delay 是事件執行的延遲時間,單位:毫秒
// function throttle(func, delay){
//     // 自定義一個定時器
//     var timer = null;
//     return function(){
//         var that = this;
//         var args = arguments
//         // timer為null表示可以發送請求了,否則還在請求中,不執行事件
//         if(!timer){
//             timer = setTimeout(function(){
//                 //執行事件處理程序
//                 func.call(that, args)
//                 //事件執行完后把定時器清除掉,下次觸發事件的時候再設置
//                 timer = null;
//             }, delay)
//         }  
//     }
// }
button1Dom.addEventListener('click',throttle(function(){console.log("節流:我發送了消息")
},1000))

頻繁的點擊,降低了發送的頻率:?

?

2.5 時間戳與計時器實現的區別

最明顯的區別就是在頻繁點擊的時候,會發現使用時間戳實現的節流會在調用的時候馬上執行,而使用計時器實現會在時間段結束時執行

第三章 總結

  • 所謂防抖,就是指觸發事件后,在 n 秒后函數才會執行,如果在 n 秒內又觸發了事件,則會重新計算函數執行時間;節流,就是指連續觸發事件,但是在 n 秒中只執行一次函數。
  • 函數節流不管事件觸發有多頻繁,都會保證在規定時間內一定會執行一次真正的事件處理函數,而函數防抖只是在最后一次事件后才觸發一次函數。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/43350.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/43350.shtml
英文地址,請注明出處:http://en.pswp.cn/news/43350.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MR300C工業無線WiFi圖傳模塊 內窺鏡機器人圖像傳輸有線無線的兩種方式

MR300C無線WiFi圖傳模使用方法工業機器人圖像高清傳輸 ? MR300C圖傳模塊基于MIPS處理器實現&#xff0c;電腦/手機連接模塊的WIFI熱點或網口即可查看視頻流 ? 模塊的USB 2.0 Host接口&#xff0c;可接入USB uvc攝像頭/內窺鏡默認輸出的視頻格式必須是MJPG ? 模塊支持接入攝…

計算機競賽 圖像識別-人臉識別與疲勞檢測 - python opencv

文章目錄 0 前言1 課題背景2 Dlib人臉識別2.1 簡介2.2 Dlib優點2.3 相關代碼2.4 人臉數據庫2.5 人臉錄入加識別效果 3 疲勞檢測算法3.1 眼睛檢測算法3.3 點頭檢測算法 4 PyQt54.1 簡介4.2相關界面代碼 5 最后 0 前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是…

在 PyTorch 中使用關鍵點 RCNN 進行人體姿勢估計--附源碼

人體姿態估計是計算機視覺領域的一個重要研究領域。它涉及估計人體上的獨特點,也稱為關鍵點。在這篇博文中,我們將討論一種在包含人類的圖像上查找關鍵點的算法,稱為Keypoint-RCNN。該代碼是使用 Pytorch 使用Torchvision庫編寫的。 假設您想要建立一名私人健身教練,可以通…

MongoDB升級經歷(4.0.23至5.0.19)

MongoDB從4.0.23至5.0.19升級經歷 引子&#xff1a;為了解決MongoDB的兩個漏洞決定把MongoDB升級至最新版本&#xff0c;期間也踩了不少坑&#xff0c;在這里分享出來供大家學習與避坑~ 1、MongoDB的兩個漏洞 漏洞1&#xff1a;MongoDB Server 安全漏洞(CVE-2021-20330) 漏洞2…

SpringBoot + Vue 微人事(十二)

職位批量刪除實現 編寫后端接口 PositionController DeleteMapping("/")public RespBean deletePositionByIds(Integer[] ids){if(positionsService.deletePositionsByIds(ids)ids.length){return RespBean.ok("刪除成功");}return RespBean.err("刪…

工業視覺相機鏡頭選型方法

一、相機選型 1、首先&#xff0c;根據檢測需求確定選用黑白/彩色、面陣/線陣相機&#xff0c;接口類型一般選擇GigE 2、確定檢測精度要求&#xff08;最小特征尺寸mm&#xff09;、視野范圍&#xff0c;一個測量精度對應幾個像素數&#xff08;一般取3-5&#xff09; 3、計…

GPT法律領域

法律領域 LaWGPT Github: https://github.com/pengxiao-song/LaWGPT 簡介&#xff1a;基于中文法律知識的大語言模型。 數據&#xff1a;基于中文裁判文書網公開法律文書數據、司法考試數據等數據集展開&#xff0c;利用Stanford_alpaca、self-instruct方式生成對話問答數據…

esp32c3 micropython oled實時天氣信息

目錄 簡介 效果展示 代碼 main.py ssd1306.py font.py 實現思路 簡介 合宙esp32c3 micropython框架&#xff0c;只支持128*64 I2C oled ssd1306驅動我優化過的&#xff0c;與其他的不一樣&#xff0c;為避免出錯&#xff0c;使用我的驅動 把下面兩個py文件放入單片機內…

SqlServer的with(nolock)關鍵字的用法介紹

舉個例子 下面就來演示這個情況。 為了演示兩個事務死鎖的情況&#xff0c;我們下面的測試都需要在SQL Server Management Studio中打開兩個查詢窗口。保證事務不被干擾。 --1、 沒有提交的事務&#xff0c;NOLOCK 和 READPAST處理的策略&#xff1a; --查詢窗口一請執行如下…

【馬蹄集】第二十三周——進位制專題

進位制專題 目錄 MT2186 二進制&#xff1f;不同&#xff01;MT2187 excel的煩惱MT2188 單條件和MT2189 三進制計算機1MT2190 三進制計算機2 MT2186 二進制&#xff1f;不同&#xff01; 難度&#xff1a;黃金 ?? 時間限制&#xff1a;1秒 ?? 占用內存&#xff1a;128M 題目…

Kotlin的Map

在 Kotlin 中&#xff0c;Map 是一種鍵值對的集合數據結構&#xff0c;用于存儲一組關聯的鍵和值。Kotlin 標準庫提供了 Map 接口和多種實現類&#xff0c;使得操作和處理鍵值對數據更加方便。下面詳細描述 Kotlin 的 Map 的用法&#xff1a; 創建 Map Kotlin 提供了幾種方式…

SQL力扣練習(十一)

目錄 1.樹節點(608) 示例 1 解法一(case when) 解法二(not in) 2.判斷三角形(610) 示例 1 解法一(case when) 解法二(if) 解法三(嵌套if) 3.只出現一次的最大數字(619) 示例 1 解法一(count limit) 解法二(max) 4.有趣的電影(620) 解法一 5.換座位(626) 示例 …

同步jenkinsfile流水線(sync-job)

環境 變量&#xff1a;env&#xff08;環境變量&#xff1a;sit/dev/simulation/prod/all&#xff09;&#xff0c;job&#xff08;job-name/all&#xff09;目錄&#xff1a;/var/lib/jenkins/jenkinsfile environment.json&#xff1a; [roottest-01 jenkinsfile]# cat env…

C++ string類的模擬實現

模擬實現string類不是為了造一個更好的輪子&#xff0c;而是更加理解string類&#xff0c;從而來掌握string類的使用 string類的接口設計繁多&#xff0c;故而不會全部涵蓋到&#xff0c;但是核心的會模擬實現 庫中string類是封裝在std的命名空間中的&#xff0c;所以在模擬…

webpack5和webpack4的一些區別

自動清除打包目錄 webpack4 // bash npm i clean-webpack-plugin -D //webpack.config.js const {CleanWebpackPlugin} require(clean-webpack-plugin); module.exports {plugins: [new CleanWebpackPlugin()} } webpack5 module.exports {output: {clean: true} } topLevel…

使用PostgreSQL構建強大的Web應用程序:最佳實踐和建議

PostgreSQL是一個功能強大的開源關系型數據庫,它擁有廣泛的用戶群和活躍的開發社區。越來越多的Web應用選擇PostgreSQL作為數據庫 backend。如何充分利用PostgreSQL的特性來構建健壯、高性能的Web應用?本文將給出一些最佳實踐和建議。 一、選擇合適的PostgreSQL數據類型 Pos…

【Vue】Mixin 混入

Vue Mixin 混入 1.簡介 混入&#xff08;mixin&#xff09;提供了一種非常靈活的方式&#xff0c;來分發 Vue 組件中的可復用功能。一個混入對象可以包含任意組件選項&#xff08;如data、methods、mounted等等&#xff09;。當組件使用混入對象時&#xff0c;所有混入對象的…

Java將時間戳轉化為特定時區的日期字符串

先上代碼&#xff1a; ZonedDateTime dateTime ZonedDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()),zone ); //2019-12-01T19:01:4608:00String formattedDate dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd") ); //2019-12-…

.git內存清理方式

查看前15個大文件 git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -15 | awk {print$1})"刪除文件夾&#xff08;public/housimg文件夾目錄&#xff09; git filter-branch --tree-filter rm -rf publ…