防抖(Debounce)和节流(Throttle)是常用的优化技术,用于控制事件触发的频率。以下是它们的示例:
1. 防抖(Debounce): 防抖的目标是在触发事件后等待一段时间,如果在这段时间内没有再次触发该事件,才执行相应的操作。如果在等待时间内又触发了该事件,则重新开始等待计时。
<body>
<input type="text" placeholder="请输入关键字">
<script>
function debounce(func, delay) {
let timer;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
console.log('打印this的值', this); // 这里打印的是input这个dom
func.apply(this, arguments);
}, delay);
};
}
// 示例:在输入框中输入文字时触发防抖函数
const input = document.querySelector('input');
function handleInput() {
console.log('Input value:', input.value);
}
const debouncedInput = debounce(handleInput, 300);
input.addEventListener('input', debouncedInput);
</script>
</body>
在上面的示例中,当用户在输入框中输入文字时,防抖函数会延迟300毫秒执行handleInput()函数,只有在连续输入停止300毫秒后,才会输出输入框的值。
2. 节流(Throttle): 节流的目标是控制事件的触发频率,在一定的时间间隔内只触发一次事件。如果在这个时间间隔内多次触发该事件,只有第一次触发会执行相应的操作,后续的触发将被忽略。
function throttle(func, delay) {
let timer;
let lastExecutedTime = 0;
return function () {
const currentTimestamp = Date.now();
if (currentTimestamp - lastExecutedTime >= delay) {
func.apply(this, arguments);
lastExecutedTime = currentTimestamp;
} else {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
lastExecutedTime = currentTimestamp;
}, delay);
}
};
}
// 示例:滚动事件时触发节流函数
function handleScroll() {
console.log('Scroll position:', window.scrollY);
}
const throttledScroll = throttle(handleScroll, 300);
window.addEventListener('scroll', throttledScroll);
在上面的示例中,当用户滚动页面时,节流函数会在每300毫秒内只触发一次handleScroll()函数,输出当前滚动位置。如果在300毫秒内多次触发滚动事件,只有第一次触发会执行相应的操作,后续的触发将被忽略。
这些是防抖和节流的简单示例,它们可以根据具体的需求进行调整和扩展。请注意,在实际开发中,也可以使用现成的防抖和节流库来方便地实现这些功能。
3.防抖(节流也差不多)为什么要使用闭包?
保护状态: 闭包可以保护内部的变量和状态,通过闭包,我们可以在外部函数中创建一个 timer 变量,并在内部函数中访问和更新这个变量,而且外部(这个外部指的是外部函数外的全局作用域或者父级函数作用域)无法直接访问或修改这个变量,从而确保计时器在适当的时间内被清除或重新设置。
延长变量寿命: 由于 JavaScript 的事件循环机制,如果不采用闭包,timer 变量会在 debounce 函数执行完毕后被销毁(垃圾回收),导致定时器无法正常工作。通过闭包,内部函数引用了外部函数的变量,使得这些变量在内部函数执行完毕后不会立即销毁,从而保持其状态和值。
函数复用: 通过闭包,我们可以灵活地将 debounce 函数应用到不同的处理函数和时间间隔上,而不需要每次都重新声明 timer 变量。这样可以提高代码的复用性和灵活性。
因此,使用闭包能够有效地实现对内部状态的管理、变量的保护和提供更好的代码组织结构,使得防抖功能能够正常运行并且具有良好的封装性。