文章目錄
- 作用
- 防抖函式
- 節流函式
- 比較
作用
- 優化高頻率執行js代碼的一種手段,js中的一些事件如瀏覽器的resize、scroll,滑鼠的mousemove、mouseover,input輸入框的keypress等事件在觸發時,會不斷地呼叫系結在事件上的回呼函式,極大地浪費資源,降低前端性能,
- 為了優化體驗,需要對這類事件進行呼叫次數的限制,
防抖函式
在事件被觸發n秒后再執行回呼,如果在這n秒內又被觸發,則重新計時,
對于函式防抖,有以下幾種應用場景:
- 給按鈕加函式防抖防止表單多次提交,
- 對于輸入框連續輸入進行AJAX驗證時,用函式防抖能有效減少請求次數,
- 判斷
scroll是否滑到底部,滾動事件+函式防抖總的來說,適合多次事件一次回應的情況
- 首先我們寫一個監聽滑鼠移動事件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function testDebounce() {
console.log('test');
}
document.onmousemove = () => {
testDebounce();
}
</script>
</body>
</html>
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-MCQvkJaf-1613098911872)(/Users/mac/Desktop/前端學習筆記/Javascript/JS高級/防抖函式與節流函式/1.gif)]](https://img.uj5u.com/2021/02/14/224517141228591.gif)
- 最簡單的防抖函式:
var timer; // 維護同一個timer
function debounce(fn, delay) {
clearTimeout(timer);
timer = setTimeout(function(){
fn();
}, delay);
}
- 為滑鼠移動事件添加防抖函式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var timer; // 維護同一個timer
function debounce(fn, delay) {
clearTimeout(timer);
timer = setTimeout(function(){
fn();
}, delay);
}
// test
function testDebounce() {
console.log('test');
}
document.onmousemove = () => {
// testDebounce();
debounce(testDebounce, 1000);
}
</script>
</body>
</html>
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YhIeNb8m-1613098911875)(/Users/mac/Desktop/前端學習筆記/Javascript/JS高級/防抖函式與節流函式/2.gif)]](https://img.uj5u.com/2021/02/14/224517141228592.gif)
-
上面例子中的debounce就是防抖函式,在document中滑鼠移動的時候,會在onmousemove最后觸發的1s后執行回呼函式testDebounce;如果我們一直在瀏覽器中移動滑鼠(比如10s),會發現會在10 + 1s后才會執行testDebounce函式(因為clearTimeout(timer)),這個就是函式防抖,
-
可以看到大大減小了onmousemove事件的呼叫次數,
-
防抖函式優化進階:
function debounce(fn, delay) {
let timer = null;
return function(...args) {
if(timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
}
}
- 進階測驗:
function debounce(fn, delay) {
let timer = null;
return function(...args) {
if(timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
}
}
// test
function testDebounce(e, content) {
console.log(e, content);
}
var testDebounceFn = debounce(testDebounce, 1000); // 防抖函式
document.onmousemove = function (e) {
testDebounceFn(e, 'debounce'); // 給防抖函式傳參
}
節流函式
每隔一段時間,只執行一次函式,
對于函式節流,有如下幾個場景:
- 游戲中的重繪率
- DOM元素拖拽
- Canvas畫筆功能
總的來說,適合大量事件按時間做平均分配觸發,
- 節流函式
function throttle(fn, gapTime) {
let _lastTime = null;
return function () {
let _nowTime = + new Date()
if (_nowTime - _lastTime > gapTime || !_lastTime) {
fn();
_lastTime = _nowTime
}
}
}
- 測驗:
let fn = ()=>{
console.log('boom')
}
setInterval(throttle(fn,1000),10)
結果是一秒打出一次boom
比較
相同點:
- 都可以通過使用 setTimeout 實作,
- 目的都是,降低回呼執行頻率,節省計算資源,
不同點:
- 函式防抖,在一段連續操作結束后,處理回呼,利用clearTimeout 和 setTimeout實作,函式節流,在一段連續操作中,每一段時間只執行一次,頻率較高的事件中使用來提高性能,
- 函式防抖關注一定時間連續觸發的事件只在最后執行一次,而函式節流側重于一段時間內只執行一次,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/259495.html
標籤:其他
下一篇:Math.random()的使用
