防抖
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数 执行时间。 ps: 重置普攻
策略
当事件被触发时,设定一个周期延时执行动作,若周期又被触发,则重新设定周期,直到周期结束,执行动作。 在后期有拓展了前缘防抖函数,即执行动作在前,设定延迟周期在后,周期内有事件被触发,不执行动作,且周期 重新设定。
防抖应用
用到防抖的地方还有很多很多,比如:搜索,当我们绑定input事件后,value每改变一次就会触发这个事件向后台请求内容,而用户此时需要搜索的内容还没写完,可我们就已经发送了很多次请求了,正确的做法是利用防抖,当用户最后一次输入后一段时间内不再输入就判定输入完成,再向后台发送请求。
再比如分页、文本编辑器实时保存(当无任何更改操作一秒后进行保存)、DOM 元素的拖拽功能实现、计算鼠标移动的距离等等。
防抖案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<input type="text" />
<script>
const inp = document.querySelector("input");
inp.oninput = debounce(sayDebounce)
function debounce(fn, interval) {
let timer = null; // 定时器
return function () {
// 清除上一次的定时器
clearTimeout(timer);
// // 拿到当前的函数作用域 因为用了箭头函数下边 所以不需要这个了
// let _this = this;
// 拿到当前函数的参数数组
// let args = Array.prototype.slice.call(arguments, 0);
// 开启倒计时定时器
timer = setTimeout (()=> {
// 通过apply传递当前函数this,以及参数 apply特性
fn.apply(this, [...arguments]);
// 默认300ms执行
}, interval || 300);
};
}
function sayDebounce(a) {
// ... 有些需要防抖的工作,在这里执行
console.log("防抖成功!");
console.log(a.target)
}
</script>
</body>
</html>
节流
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。 节流会稀释函数的执行频率。
对于节流,有多种方式可以实现 时间戳 定时器 束流等。
ps : 技能CD :
策略
固定周期内,只执行一次动作,若没有新事件触发,不执行。周期结束后,又有事件触发,开始新的周期。
特点:
连续高频触发事件时,动作会被定期执行,响应平滑
节流案例
<button id="debounce">点我防抖!</button>
<script>
// 1、获取这个按钮,并绑定事件
var myDebounce = document.getElementById("debounce");
// myDebounce.addEventListener("click", debounce(sayDebounce));
myDebounce.onclick = throttle(sayDebounce);
function throttle(fn, interval) {
let timer = null; // 定时器
let firstTime = true; // 判断是否是第一次执行
// 利用闭包
return function () {
// 拿到函数的参数数组
let args = Array.prototype.slice.call(arguments, 0);
// 拿到当前的函数作用域
let _this = this;
// 如果是第一次执行的话,需要立即执行该函数
if (firstTime) {
// 通过apply,绑定当前函数的作用域以及传递参数
fn.apply(_this, args);
// 修改标识为null,释放内存
firstTime = null;
}
// 如果当前有正在等待执行的函数则直接返回
if (timer) return;
// 开启一个倒计时定时器
timer = setTimeout(function () {
// 通过apply,绑定当前函数的作用域以及传递参数
fn.apply(_this, args);
// 清除之前的定时器
timer = null;
// 默认300ms执行一次
}, interval || 3000);
};
}
// 3、需要进行防抖的事件处理
function sayDebounce(a) {
// ... 有些需要防抖的工作,在这里执行
console.log(111);
console.log(a.target);
}
function throttle(fn,wait) {
let timer;
return function() {
let args = arguments;
if(!timer) {
timer = setTimeout(()=>{
timer = null;
fn.apply(this,args);
},wait)
}
}
}