防抖与节流
防抖
<script>
//input输入事件
document.getElementsByTagName('input')[0].oninput = debounce(submit,500)
//模拟接口发送
function submit(val) {
console.log('发送请求',val.target.value);
}
//防抖封装fn
function debounce(fn, delay) {
console.log('防抖执行');
let timer = null
return function (...arg) {
console.log('input事件',timer);
if(timer){
clearTimeout(timer)
timer = null
}
timer = setTimeout(() => {
console.log(timer);
fn.apply(this, arg)
}, delay);
}
}
</script>
<!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>防抖与节流</title>
</head>
<body>
防抖: 用户来连续快速点击的请求的时候,请求只会触发一次(因为请求之后必须延迟一秒后才可以继续发请求,否则计时器清零重新开始计算)
节流:用户连续快速的点击请求的时候,请求会间隔(1秒)时间内触发
<hr>
防抖:通过setTimout的方式,在一定时间间隔内,将多次触发变成一次触发
节流:减少一段时间的触发频率
<hr>
<button id="btn1">触发防抖请求</button>
<button id="btn2">触发节流请求</button>
<script>
let btn1 = document.getElementById('btn1')
let btn2 = document.getElementById('btn2')
btn1.addEventListener('click', debounce(submit, 1000), false) //防抖
btn2.addEventListener('click', throttle(submit, 1000), false) //节流
function submit(e) {
console.log(arguments);
console.log(this);
console.log('触发了');
}
function debounce(fn, delay, add) { //防抖
console.log(this); //这里的this指向是Window
let timer = null
// 调用下面函数的this 指向的就是触发当前函数的按钮 // <button id="btn1">触发防抖请求</button>
// 如果下面的function 改用箭头函数 this就会指向window 就不能判断是哪个按钮触发了
return function () {
var firstClick = !timer
if (timer) { clearTimeout(timer) } //这一部是为了清除多个缓存的计时器 ,若不清除,每个定时器的执行函数依然会触发
if (firstClick) {
fn.apply(this, arguments) //这里的this 指向可以区分是点击了那个方式的请求
}
timer = setTimeout(() => {
timer = null
}, delay);
}
}
function throttle(fn, delay) { //节流
var begin = 0
return function () {
var cur = new Date().getTime()
if (cur - begin > delay) {
fn.apply(this, arguments)
begin = cur
}
}
}
</script>
</body>
</html>