n 秒内只运行一次
,若在 n 秒内重复触发,只有一次生效;n 秒后在执行该事件
,若在 n 秒内被重复触发,则重新计时应用场景:
正常情况:快速点击按钮,无论你点的有多快,只要点了一次,日志就会打印一次?
需求:在快速点击的过程中,如何只让最后一次能产生效果?
示例代码:
核心:
<body>
<button class="button">点击</button>
<script type="text/javascript">
<!-- 防抖:用户点击=》多次点击会多次发送请求=》浪费性能-->
//1、添加点击事件
//2、添加防抖:1、定时器,2、高阶函数
const button = document.querySelector('button');
//防抖:在规定的时间点击一次
button.addEventListener('click', debounce(change, 2000))
//高阶函数:1、函数的返回值是一个函数或者参数是一个函数
function debounce(fn, time=250) {
let timer = null;//1、这个变量会保存在内存中,只会创建一次
//用到定时器,规定的时间内只执行一次
return function (e) {
console.log("this", this);
//判断定时器是否生成,如果生成了,清除上一次点击的定时器,保证只有最后一次点击的定时器才有用
if (timer) {
clearTimeout(timer);
}
let firstClick = !timer;
//如果是第一次点击就立即执行
if (firstClick) {
//拿到外部函数的this,即按钮这个节点,将fn()函数的this指向
fn.apply(this, arguments);//处理业务逻辑
}
timer = setTimeout(() => {
timer = null;
}, time)
}
}
function change(e) {
console.log(e);
}
</script>
</body>
应用场景:
需求:如果你持续触发事件,每隔一段时间,只会执行一次事件
实现的两种方式:
1、定时器
核心:
<body>
<button class="button">点击</button>
<script type="text/javascript">
const button = document.querySelector('button');
button.addEventListener('click', throttle(change, 2000));
function change() {
console.log("发送请求了...");
}
function throttle(fn, time=250) {
/*注意这里用到了闭包*/
let flag = true;//设置节流阀;这个变量会保存在内存中,只会创建一次
return () => {
if (flag) {
flag = false;//flag值变为false
//发起请求
fn();
//通过定时器,2s后将flag的值变为true,点击按钮才可再次发送请求
setTimeout(() => {
flag = true
}, time)
}
}
}
</script>
</body>
2、时间戳
核心:
<body>
<button class="button">点击</button>
<script type="text/javascript">
const button = document.querySelector('button');
button.addEventListener('click', throttle(change, 2000));
function change() {
console.log("发送请求了...");
}
function throttle(fn, time=250) {
/*注意这里用到了闭包*/
let begin = 0;//设置时间戳
return () => {
//获取当前时间戳
let date = new Date().getTime();
//判断当前的时间戳与上一次点击的时间戳的差是否大于time
if (date - begin > time) {
fn();
begin = date;
}
}
}
</script>
</body>