防抖
指触发事件后在n秒内函数只执行一次,若在n秒内再次触发,则重新计算
例如点击按钮,两秒内触发点击函数,但是你在第1.5秒时又点了一下,这时,函数触发时间重新计算;又如下拉触底加载下一页的功能
<div id="content" style="height: 150px; line-height: 150px; text-align: center; background-color:gray;color: #fff; font-size: 50px; "></div>
<script>
let num = 1;
let content = document.getElementById("content");
function count() {
content.innerHTML = num++;
}
content.onmousemove = count;
</script>
// 防抖 debounce
// 让输入完毕后过2秒再查询(延迟执行)
function debounce(func, wait) {
let timeout; // 定时器
return function() {
if (timeout) clearTimeout(timeout); // 取消之前的任务
timeout = setTimeout(function() {
func.apply(this); // this是作用域,指向当前对象,当前对象又是window,因为是全局函数
// apply是执行func函数
}, wait)
}
}
content.onmousemove = debounce(count, 2000);
// 让输入完毕立即查询,但是过2秒后才能再次查询(立即执行)
function debounce(func, wait) {
let timeout;
return function() {
if (timeout) clearTimeout(timeout);
let callNow = !timeout; // 类型转换
timeout = setTimeout(() => { // 增加一个定时器
timeout = null; // 清空当前定时器句柄
}, wait);
if (callNow) func.apply(this); // 第一次执行
}
}
content.onmousemove = debounce(count, 2000);
节流
指连续发生的事件在n秒内只执行一次函数
如搜索、即时查询功能,当查询数据量太大时,一定要在一定时间内限制查询次数,能减少后端请求压力
// 节流 throttle
// 两种
// 定时器方式,固定的时间发请求
function throttle(func, wait) {
let timeout; // 定义一个定时器句柄
return function() {
if (!timeout) { // 是否存在定时器
timeout = setTimeout(() => { // 创建一个定时器
timeout = null;
func.apply(this); // func==count apply调用count
}, wait);
}
}
}
content.onmousemove = throttle(count, 2000);
// 时间戳的方式 移动端多用这种时间戳方式,提高性能
// 鼠标不管怎么移动,不断触发函数,都是2秒发送一次请求,没有发送多于请求
function throttle(func, wait) {
let prev = 0; // 上次记录时间
return function() {
let now = Date.now(); // 当前时间
if (now - prev > wait) { // 当前时间-上次时间>等待时间
func.apply(this); // 执行函数 发送请求
prev = now; // 重置上次记录时间
}
}
}
content.onmousemove = throttle(count, 2000);
最后
在学习过程中,代码写的比较乱,我自己看也许会感觉比较清晰,但是读者看着就会稍有迷糊,建议结合自身的学习资料和笔记对照着来看。