什么是节流(throttle)
节流就是在一段时间之内,只能触发一个函数。如果在这一段时间之内多次触发这个函数也没有用,只能有一次生效。
简易版节流的实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
height: 2400px;
}
</style>
</head>
<body>
<script>
let flag = true
window.onscroll = function () {
// 现在开始实现节流
if (flag) {
setTimeout(() => {
console.log('人类朋友')
// 执行完之后需要记得将flag置回 true 不然后面触发该事件就再也不会执行事件对应的回调函数了
flag = true
}, 1000)
}
// 执行一个定时器之后就将 flag 置为 false 也就是在定时器规定的事件之内最多只能执行一次 onscroll 事件对应的回调函数
flag = false
}
</script>
</body>
</html>
解释
我滚动页面的时候会触发其对应onscroll事件的回调函数。首先定义一个全局变量flag。我将回调函数触发的条件定义为flag为真的情况。
最开始flag为真,满足if语句,执行定时器函数。这个时候需要注意,在定时器函数还在定时的期间,代码已经执行到下方的flag = false了,这代表什么?这代表后续再疯狂滚动页面也不会满足if (flag)了。直到什么时候满足?直到定时器函数计时完成,将flag重新置为true
下面封装一个节流函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
height: 2400px;
}
</style>
</head>
<body>
<script>
let throttle = function (fn, delay) {
let flag = true
return function () {
// 现在开始实现节流
if (flag) {
setTimeout(() => {
fn()
// 执行完之后需要记得将flag置回 true 不然后面触发该事件就再也不会执行事件对应的回调函数了
flag = true
}, delay)
}
// 执行一个定时器之后就将 flag 置为 false 也就是在定时器规定的事件之内最多只能执行一次 onscroll 事件对应的回调函数
flag = false
}
}
window.onscroll = throttle(function () {
console.log('hello')
}, 1000)
</script>
</body>
</html>
解释
将第一版的函数作为函数throttle的返回值,将throttle函数执行后返回的匿名函数作为事件onscroll的回调函数,向throttle函数传入函数fn与定时事件delay即可。