防抖与节流
防抖
防抖的实现目的是为了防止一个事件过于频繁的触发,降低性能,举一个最简单的例子input事件,每一次输入内容都会向后台发送请求,如图:
防抖就是可以很好的解决这个问题,首先我们的目的是为了获取输入框中最后一次输入的内容,所以我们可以添加一个一秒的延迟器,来获取到最后一次输入的内容
<!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>
let inp = document.querySelector('input')
let timeId
inp.addEventListener('input', function () {
//定时器不为空则清除定时器
if (timeId !== null) {
clearTimeout(timeId)
}
//一秒后获取输入的value值
timeId = setTimeout(() => {
console.log(this.value);
}, 1000);
})
</script>
</body>
</html>
这个问题虽然解决了,但是并不能进行业务开发,我们可以运用闭包来封装一个防抖的方法
let inp = document.querySelector('input')
inp.addEventListener('input', debounce(function () {
//this指向了window
console.log(this.value);
}, 1000))
//闭包进行防抖的功能封装
//fn为上面传入的函数 delay为延迟时间
function debounce(fn, delay) {
let timeId
return function () {
//定时器不为空则清除定时器
if (timeId !== null) {
clearTimeout(timeId)
}
//一秒后获取输入的value值
timeId = setTimeout(() => {
//需要改变this指向,inp调用了fn所以指向改为了inp
fn.call(this)
}, delay);
}
}
结果如图:
节流
节流的实现目的与防抖一样都是为了阻止一个事件频繁的触发,最常用的场景就是页面滑轮滚动时触发scroll事件,如图:
我们的目的是控制滚轮事件的执行次数,所以我们可以添加一个一秒的延迟器,一秒内只能获取到一次的数据。
<!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>
<style>
body {
height: 2000px;
}
</style>
</head>
<body>
<script>
let flag = true
window.addEventListener('scroll', function () {
if (flag) {
setTimeout(() => {
console.log('swh');
flag = true
}, 1000)
}
flag = false
})
</script>
</body>
</html>
同样进行函数封装
window.addEventListener('scroll', throttle(function () {
//this指向了window
console.log('swh');
}, 1000))
//闭包进行节流的功能封装
//fn为上面传入的函数 delay为延迟时间
function throttle(fn, delay) {
let flag = true
//定时器不为空则清除定时器
return function () {
//判断改变进入定时器的次数
if (flag) {
setTimeout(() => {
//这个案例可不写call,因为指向都为window,但为了以后的业务开发写上
fn.call(this)
flag = true
}, delay)
}
flag = false
}
}
结果如图