1.防抖
触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
var time = null;
document.onmousewheel = function(e){
if (time) {
clearTimeout(time)
}
time = setTimeout( () => {
/* 进行滚动操作 */
time = null
}, 100)
}
# 第一次滑动时 time 是null ,直接执行 setTimeout ,在 0.1s 内如果又继续滑动了滚轮,
# 就会清除上一次的 setTimeout ,直到在 0.1s 内没有滑动滚轮,就会执行 setTimeout 中
# 的内容。
2. 节流
高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
下面是js代码,这种方式有点不好理解
function throttle() {
let canRun = true; // 通过闭包保存一个标记
return function () {
console.log(canRun)
if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
canRun = false; // 立即设置为false
setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
// 当定时器没有执行的时候标记永远是false,在开头被return掉
console.log(1)
canRun = true;
}, 1000);
};
}
window.addEventListener('resize', throttle());
# 当函数被注册的时候,定义了 canRun 为 true,之后返回一个函数,
# 每当事件被触发的时候,执行返回的函数中的内容。首先判断 canRun,
# 如果为 true 就往下执行,然后设 canRun 为 false,执行定时器,
# 在接下来的 1s 内,如果再次触发 resize 事件,canRun 的值是 false ,
# 会直接 return 空,不会执行任何操作。当 1s 后执行了定时器中的
# 内容并设置 canRun 为 true 后,触发事件才会重新执行定时器。
***注意***
1. 在添加事件的时候,后面的函数是加()的。正因为这个括号,所以在注册
事件的时候,let canRun = true 会被执行一次,而在事件被触发的时候,
let canRun = true 是不会被执行的,只有在被注册时会被执行一次。
2. 触发事件以后,执行的是 throttle 函数返回的函数,而不是 throttle
函数。
这两种方式的区别:第一种是当 0.1s 内再次触发事件,会消除定时器,重新计算,适用于滚轮滚动后页面的切换。因为用户滚轮切换页面时,一次会滚动很多下;第二种是如果事件一直在触发,但是每 1s 会执行一次。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。