js防抖和节流


防抖


触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。


  • 示例
  • 游戏玩家看到法师怒气值满可能疯狂点击,但技能触发有一个蓄力过程,频繁触发则重新蓄力
  • 思路:
  • 每次触发事件时都取消之前的延时调用方法
preventShake = (fn) => {
let timer = null; // 创建定时器id
return () => {
clearTimeout(timer); // input事件频繁触发,清除之前定时器
timer = setTimeout(() => { // 创建新定时器,保证限定时间间隔fn只执行一次
fn();
}, 500);
};
}
test = () => {
console.log(' prevent shake success');
}
//创建数输入框
document.querySelector('body').appendChild(document.createElement('input'))
//事件绑定
document.querySelector('input').oninput = preventShake(test)

带参数

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>

<body>
<script>

/**
* @example 防抖函数
*/
const preventShake = (fn, t = 1000) => {
let timer = null; // 创建定时器id
return (...args) => {
clearTimeout(timer); // input事件频繁触发,清除之前定时器
timer = setTimeout(() => { // 创建新定时器,保证限定时间间隔fn只执行一次
fn(...args);
}, t);
};
}
const test = (a, b, c) => {
console.log(' prevent shake success', a, b, c);
}
//创建数输入框
document.querySelector('body').appendChild(document.createElement('input'))

const preventShakeTest = preventShake(test, 3000)
//事件绑定
document.querySelector('input').oninput = () => {
preventShakeTest(1, 2, 3)
}

</script>
</body>

</html>

节流


高频事件触发,但在n秒内只会执行一次



  • 示例
  • 即便玩家疯狂点击,技能触发速度也不会变快
  • 思路:
  • 每次触发事件时都判断当前是否有等待执行的延时函数

throttle = (fn) => {
let lock = true; // 函数外设置状态锁,默认开启
return () => {
if (!lock) return; // 在函数开头判断标记是否为true,不为true则return,住址后续程序进行
lock = false; // 改变状态锁
setTimeout(() => {
fn()
// 函数执行完,回调中改变状态锁
lock = true;
}, 1000);
};
}
test = () => {
console.log('throttle');
}
//创建数输入框
document.querySelector('body').appendChild(document.createElement('input'))
//事件绑定
document.querySelector('input').oninput = throttle(test)