防抖
函数防抖:短时间多次触发同一事件,只执行 最开始 或 最后 一次操作。
function debounce(func, ms = 1000) { let timer; return function(...args) { console.log(args); if (timer) { clearTimeout(timer); } timer = setTimeout(() => { func.apply(this, args); }, ms); }; } const task = () => {console.log('run task')}; const debounceTask = debounce(task, 1000); window.addEventListener('click', debounceTask); // click 可以换成 scroll
防抖原理:
就 click 来说,如果 1s 内,点击很多次的话,debounceTask(指匿名函数) 就会执行很多次。那 task 函数也会多次调用,造成不必要的浪费。如图说明吧:


对 debounce 函数返回的匿名函数中 args 参数(这里可忽略)的存在作出说明:
const debounceTask = debounce(task, 1000) 其实返回的是匿名函数。
点击页面触发 window.addEventListener('click', debounceTask) 事件,debounceTask 会执行。
这里 debounceTask 没有传递参数,打印 args 会看到有个事件对象,这里的原因是因为:
在浏览器中,如果函数执行没有传递参数,会默认有个浏览器事件对象作为参数,如监听的是点击 click 事件的话 args 就是 [PointerEvent]

将 click 换成 scroll,如果在函数不防抖,要执行很多次了~

完整案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, maximum-scale=1, minimum-scale=1,initial-scale=1"/> <title>Title</title> <style> body { overflow: scroll; height: 10000px; border: 2px solid; } input { margin-left: 20px; width: 20px; height: 20px; } </style> </head> <body> <p>函数防抖:短时间多次触发同一事件,只执行最后或最开始的一次。</p> <p>这里以点击事件做测试</p> <input type="checkbox"/> <input type="checkbox"/> <input type="checkbox"/> <input type="checkbox"/> <input type="checkbox"/> <script> function debounce(func, ms = 1000) { let timer; console.log("匿名函数前的 timer", timer); return function(...args) { console.log("匿名函数后的 timer", timer); if (timer) { clearTimeout(timer); } timer = setTimeout(() => { func.apply(this, args); }, ms); }; } const task = () => {console.log('run task')}; const debounceTask = debounce(task, 1000); window.addEventListener('click', debounceTask); </script> </body> </html>
<script>
/*
节流:函数在一段时间内多次调用,仅第一次有效。
防抖:函数在一段时间内多次调用,仅最后一次有效。
* */
// window.addEventListener('scroll', throttle2(scrollFun, 1000));
window.addEventListener('scroll', debounce(scrollFun, 500));
function scrollFun(e) {
console.log('窗口大小改变了');
}
/* 节流—时间戳方式 */
function throttle(func, delay) {
var last = 0;
return function () {
var now = Date.now();
/*
一开始滚动的时候就执行,后面是隔一定秒数再执行,再滚动时,先获取的 now 值,间隔时间 超过 delay 时间的话 ,now > delay + last,执行函数。
* */
if (now >= delay + last) {
func.apply(this, arguments);
last = now;
} else {
console.log('********** wait ');
}
}
}
/* 节流—定时器方式 */
function throttle2(func, delay) {
var timer = null;
return function () {
if(!timer) {
func.apply(this, arguments);
timer = setTimeout(function() {
timer = null;
}, delay);
} else {
console.log('********** wait ');
}
}
}
/* 防抖 */
function debounce(func, delay) {
var timeout;
return function () {
clearTimeout(timeout);
timeout = setTimeout(() => {
console.log('run')
func.apply(this, arguments);
}, delay);
}
}
</script>
不开始最难,迟迟不开始变得又难又慌~

浙公网安备 33010602011771号