16. 防抖 和 节流(手写)
对 DOM 进行操作或者发送 Ajax 请求进行资源的加载,这样是操作很消耗性能的,JS是单线程,里面有这个的机制叫事件轮训机制,DOM 操作会触发页面的重排。
作用:限制函数的执行次数;
防抖:回城读条。
通过setTimeout的方式,在一定的时间间隔内,将多次触发改成一次触发,执行最后触发事件的最后一次。
即按最后一次触发重新计算时间
比如一个按钮,3秒后才触发,3秒内无论你点多少次,它都只触发一次。
函数防抖源码实现:
function debounce(handler, delay) {
let timer = null;
return function () {
if (timer) {
clearTimeout(timer);
} else {
timer = setTimeout(() => {
// 改变this指向为调用debounce所指的对象
handler.apply(this, arguments);
}, delay);
}
}
}
应用场景:
-
实时搜索
-
防止反复提交
var btn = document.getElementById('input');
btn.addEventListener('click', debounce(submit));
// submit模拟ajax提交
function submit(e){
console.log(1);
}
节流:技能CD。
节流:减少一段时间内的触发频率,第一次发生请求后,响应没回来就不能发送第二次。
函数节流源码实现:
// 通过时间戳的方式
function throttle(handler, delay) {
//last初始时间
let last = 0;
return function() {
//获取当前时间戳
let now = new Date().getTime();
//当前时间间隔 = now - last
//这次点击的时间 - 上一次点击的时间 > delay,才执行
if(now - last > delay) {
handler.apply(this, arguments);
last = now;
}
}}
应用场景:
-
窗口调整 (scroll 滚动事件)
-
页面滚动 (瀑布流的布局或者进行动态页面的加载)
-
抢购疯狂点击 (脚本式的触发事件进行疯狂点击,向服务器发送疯狂的请求,服务器会崩溃)
var oDiv = document.getElementById('show'); var oBtn = document.getElementById('btn'); function buy(e) { console.log(this, e); oDiv.innerText = parseInt(oDiv.innerText) + 1; } oBtn.onclick = throttle(buy, 1000);
-
频繁提交操作