先上結論: 防抖 :只執行最後一次 (常用語輸入框) 節流: 控制執行的次數 (常下拉滾動條時進行數據請求) 防抖代碼: (這是未封裝的,防抖代碼和業務代碼寫在一起了) <body> <input type="text" /> <script> // 防抖:用戶觸發事件過於頻繁,只要最後一次事件的操 ...
先上結論:
防抖 :只執行最後一次 (常用語輸入框) 節流: 控制執行的次數 (常下拉滾動條時進行數據請求) 防抖代碼: (這是未封裝的,防抖代碼和業務代碼寫在一起了)<body> <input type="text" /> <script> // 防抖:用戶觸發事件過於頻繁,只要最後一次事件的操作 let inp = document.querySelector('input') //定義全局變數 t let t = null inp.oninput = function () { if (t !== null) { clearTimeout(t) } t = setTimeout(() => { console.log(this.value) }, 500) } </script> </body>
這是封裝後的,同時利用了閉包:
<body> <input type="text" /> <script> let inp = document.querySelector('input') inp.oninput=debounce(function(){ console.log(this.value); },500) // 封裝防抖函數 //fn 為傳入的業務邏輯 delay 為延遲時間 function debounce(fn,delay){ let t = null; return function () { if (t !== null) { clearTimeout(t) } t = setTimeout(() => { // 使用call 改變 this的指向 如果不更改的話,再上面調用的 this.value 中this 指向為window fn.call(this); }, delay) } } </script> </body
節流代碼:(這是未封裝的,防抖代碼和業務代碼寫在一起了)
<style> body { height: 2000px; } </style> <script> // 節流 控制執行的次數 let flag =true window.onscroll=function(){ if(flag){ setTimeout(()=>{ console.log("hello world"); flag=true },500) } flag =false } </script>
和防抖類似,也進行了封裝,代碼如下:
<style> body { height: 2000px; } </style> <script> window.onscroll = throttle(function () { console.log('hello world') }, 500) function throttle(fn, delay) { let flag = true return function () { if (flag) { setTimeout(() => { flag = true // 使用call 改變 this的指向 fn.call(this) }, delay) } flag = false } } </script>
這裡解釋一下flag 的作用。按照執行順序講下吧,從上到下分別為(1 2 3):
(先執行的)第一個 let flag = true; 先定義flag,用來判斷使用運行定時器。相信都看得懂,廢話不多說。
(第二執行)第三個 調用定時器之後,需要將 flag 暫時定義為 flag 避免短時間再次觸發定時器。
(第三個執行的) 第二個 先講下,為啥第二個最後一個執行,這是因為 js 的同步與非同步。 js會先執行同步任務,碰到非同步任務 會加到 另外一個線程(只是這樣解釋,其實不是) 等待其運行結束後,再進行調用。要是不明白,可以先去百度搜索下,同步與非同步 的概念。
這樣的話,在定時器 運行結束後,flag 就被改為了 true 用來等待 下次激活使用。
如有解釋不對的地方,還望指正。
本文來自博客園,作者:一粒金燦米,轉載請註明原文鏈接:https://www.cnblogs.com/zy-feng/p/16819631.html