简述:js的防抖功能大家都比较熟悉,这里重新给大家详细的介绍一下js防抖函数的解析与应用,防抖就是某一高频事件不断被触发,仅在最后一次真正执行事件处理代码,将多次执行变为最后一次执行,具体点就是我们在触发高频事件后,n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。
JavaScript防抖函数详解
防抖函数是JavaScript中常用的一种函数优化技术,可以有效减少一些高频率触发的事件所带来的性能问题。本文将详细介绍JavaScript防抖函数的实现原理、应用场景和使用方法。
防抖函数的实现原理?
防抖函数的实现原理非常简单,就是在一定时间内只执行最后一次触发的事件,忽略之前触发的所有事件。具体实现方法如下:
- 设置一个定时器,当触发事件时,如果定时器存在,则清除定时器。
- 重新设置一个定时器,延迟一定时间后执行事件。
- 如果在延迟时间内再次触发事件,则重复1和2的步骤。
- 如果延迟时间到了,执行事件。
防抖函数的应用场景?
防抖函数适用于一些高频率触发的事件,比如:
- 输入框实时搜索,避免频繁请求后端接口。
- 浏览器窗口resize事件,避免频繁触发DOM操作。
- 滚动条滚动事件,避免频繁更新DOM。
- 按钮点击事件,避免重复提交表单。
防抖函数的使用方法?
- 手写实现防抖函数(js版本)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>防抖</title>
<style>
.btn {
width: 200px;
height: 100px;
border-radius: 12px;
background: #ccc;
line-height: 100px;
font-size: 18px;
text-align: center;
cursor: pointer;
}
</style>
</head>
<body>
<div class="btn">点击</div>
</body>
<script>
// 获取元素
const btn = document.querySelector(".btn");
// 给元素添加点击事件监听,点击时,执行debounce函数
btn.addEventListener("click", debounce(handlePayment, 1000));
/**
* fn 点击按钮时要执行的函数
* delay 延迟时间
* return 防抖函数
* */
function debounce(fn, delay) {
// 设置定时器标识(写在return函数外面,方便下面内部函数获取)
let timer = null;
// 返回函数,不然调用debounce会立即执行此函数
return function () {
// fn 指向 this
let context = this;
// fn 参数
let args = arguments;
// 先清除定时器
clearTimeout(timer);
// 设置定时器
timer = setTimeout(() => {
// 函数调用
fn(context, args);
}, delay);
};
}
// 定义提交时的函数
function handlePayment() {
console.log("付款成功=>", Math.random());
}
</script>
</html>
- 手写实现防抖函数(ts版本)
function debounce(fun: SourceFunction, delay: number = 500): TargetFunction {
// 使用类型推断
let timer: ReturnType<typeof setTimeout>;
return async function (...args: any[]) {
if (timer) {
clearTimeout(timer);
}
return new Promise(resolve => {
timer = setTimeout(() => {
clearTimeout(timer);
resolve(fun.apply(null, args));
}, delay);
});
};
}
这样用户在频繁点击按钮时,就可以执行延迟操作,防止函数多次调用,完成防抖功能;
手写实现防抖函数注意事项:
(1)、debounce函数不能直接调用fn函数,因为按钮绑定的事件函数是直接调用的,所以使用返回函数,否则函数会立即执行;
(2)、每次点击先清除延时操作,clearTimeout不能清除一个没有定义的变量名,所以需要先定义一个变量timer用来清除和定义延时操作;
(3)、在函数外层定义timer,函数内部方便使用,让这些独立的执行函数有联系;
(4)、调用函数fn,容易忽略this指向,需要将this指向调用者。