防抖
高頻事件觸發(fā),但 n 秒內(nèi)函數(shù)只執(zhí)行一次,如果 n 秒內(nèi)又觸發(fā)了事件,則重新計算時間
function debounce(fn, wait) {
var time = null;
return function() {
clearTimeout(time)
time = setTimeout(() => {
fn.apply(this, arguments)
}, wait);
}
}
function demo() {
console.log('防抖啦')
}
// 用句柄事件綁定調(diào)用debounce事件,所以this為div節(jié)點對象
document.querySelector('div').addEventListener('scroll', debounce(demo, 1000))
用例:
- 電梯檢測到有人進入,延遲10秒關門,如果10秒內(nèi)有人進入,則繼續(xù)延遲10秒關門,直到10秒內(nèi)無人進入
- 快速修改購物車商品數(shù)量,只有停頓超過規(guī)定的時間,才會向后端發(fā)送數(shù)據(jù)
- 搜索框輸入,停頓后再發(fā)送 ajax 請求
- 用戶名、手機號、郵箱等輸入驗證
- 容器或瀏覽器窗口大小改變后,只需窗口調(diào)整完后,再執(zhí)行 resize 事件中的代碼,防止重復渲染
節(jié)流
高頻事件觸發(fā),但 n 秒內(nèi)函數(shù)只執(zhí)行一次,相當于稀釋函數(shù)的執(zhí)行頻率
function throttle(callback, delay) {
var previous = 0;
return function() {
var now = +new Date();
if (now - previous > delay) {
callback.apply(this, arguments);
previous = now;
}
}
}
function getUserAction() {
console.log(`每1秒內(nèi)打印一次`)
}
document.querySelector('div').addEventListener('click', throttle(getUserAction, 1000))
用例
- 拖動元素,mousemove 函數(shù)會觸發(fā)多次,如果回調(diào)函數(shù)業(yè)務復雜,會影響性能,此時使用js節(jié)流,如10ms觸發(fā)一次回調(diào),可大大減少性能開支
- 鼠標拖動調(diào)整容器大小
- 內(nèi)容滾動