JavaScript 防抖
在本文中,我们将讨论 JavaScript 的防抖方法及其实现。
什么是防抖
防抖是一种用于提高浏览器性能的 JavaScript 方法。网页上可能有一些需要耗时计算的功能。如果频繁应用此类方法,可能会极大地影响浏览器性能,因为 JavaScript 是单线程语言。防抖是一种编程技术,用于确保耗时活动不会导致网页性能下降。换句话说,防抖方法在调用时不会立即执行,而是等待一段预定时间后再执行。当我们再次调用相同的过程时,之前的过程被取消,计时器被重置。
防抖与节流是类似的,它们都有助于改善 Web 应用的性能。不过,它们适用于不同的情况。当我们只关注最终状态时,使用防抖。例如,它们等待用户输入完成以检索输入提示的搜索结果。如果我们希望以规定的速度管理所有中间状态,节流是最好的工具。
防抖的实现
让我们通过一个示例来了解程序中防抖方法的实现。
const debounce = (func, wait) => {
let timeout;
return function mainFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(delay, wait);
};
};
返回另一个函数的高阶函数称为防抖函数。它用于创建一个闭包,将 func 和 wait 函数参数以及 timeout变量 的值保存起来。以下变量的定义如下:
- Func: 我们希望在防抖时间后执行的 func 函数。
- Wait: 在最后接收到的操作后,防抖函数可以等待多长时间才能执行func。
- Timeout: timeout函数是用来表示正在运行的防抖的值。
示例
让我们来看一个示例,了解JavaScript中的 debouncing() 方法。在下面的示例中,一个按钮连接到一个事件监听器,该监听器调用防抖函数。防抖函数有 两个参数 :一个是函数,另一个是一个数值(时间)。这里声明一个 计时器 ,它的名字就是它的含义,并在一定时间后调用防抖函数。
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Debounce</h1>
<input type = "button" id="debounce" value = "Click Here">
<script>
var button = document.getElementById("debounce");
const debounce = (func, wait) => {
let debounceTimer
return function() {
const context = this
const args = arguments
clearTimeout(debounceTimer)
debounceTimer
= setTimeout(() => func.apply(context, args), wait)
}
}
button.addEventListener('click', debounce(function() {
alert("Hello\n This message will be displayed after 3 seconds, and no matters how many times we click the button.")
}, 4000));
</script>
</body>
</html>
输出: 在执行上述代码后,我们将获得如下所示的输出结果:
如上面的截图所示,有一个 “点击这里” 按钮。当 点击这里 按钮被按下时,会出现一个警告框并显示一个警告消息。该功能每次更新,这意味着如果在延迟时间(4秒)之前按下按钮,则会清除初始计时器,并启动一个新的计时器。使用 clearTimeOut() 函数来完成这个任务。
使用立即执行函数实现防抖函数
下面的防抖实现返回一个函数,只要被调用就不会执行。在 N毫秒 的不活动时间后,函数将被再次调用。当函数以初始函数作为参数进行调用时,它会立即调用函数,并在等待一段时间后再次调用。
function debounce(func, wait, immediate) {
var timeout;
return function mainFunction() {
var cont = this;
var args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(cont, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(delay, wait);
if (callNow) func.apply(cont, args);
};
};
Debounce返回一个函数,当传递一个函数和一个时间间隔时,可以将该函数传递给事件监听器。
var returnedFunction = debounce(function() {
}, 3000);
window.addEventListener('resize', returnedFunction);
示例
让我们举一个示例来理解带有立即执行函数的防抖函数的使用方法。
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript Debounce</h1>
<button id="debounce">
Click here
</button>
<script>
var button = document.getElementById("debounce");
const debounce = (func, wait, immediate)=> {
var timeout;
return function executedFunction() {
var cont = this;
var args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(cont, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(cont, args);
};
};
button.addEventListener('click', debounce(function() {
alert("This message will be displayed after 3 seconds, and no matters how many times we click the button.")
}, 3000));
</script>
</body>
</html>
输出: 执行上面的代码后,我们将得到下面截图中显示的输出。
应用场景
防抖可以用来实现推荐文本,在用户停止输入之前,我们等待几秒钟然后提供文本。因此,在每次按键后我们等待几秒钟再进行建议。防抖经常被用在类似于 Facebook 和 Twitter 这样的内容加载网站上,用户持续滚动。因为有很多视频和照片,如果滚动事件触发得太频繁,会影响性能。因此,在滚动情况下必须使用防抖。