前言:节流一共有三种形态,不同的需求下,需要使用不同的形态,在此处对三种形态进行分解记录.本文为了让新手玩家更易理解,未使用apply,arguments参数传递等相关内容,高手可以自行补充. 最后有【完整代码】,可直接复制到html运行.
第一形态(首次触发延迟):点击【并不会立即触发】,需要等待设置的节流时间结束,然后【触发】.
function throttle1(fn, wait) {
let timer = null;
return function () {
if (!timer) {
timer = setTimeout(() => {
timer = null;
fn()
}, wait);
}
}
}
第二形态(末尾一次不触发):点击【立即触发】,在节流冷却时间内多次点击,将直接被忽略,冷却结束时,【不会触发】.
function throttle2(fn, wait) {
let pre = 0;
return function () {
let now = Date.now()
if (now - pre > wait) {
fn()
pre = now
}
}
}
第三形态:点击【立即触发】,在节流冷却时间内多次点击,将被缓存,冷却结束时,【立即解发】.
function throttle3(fn, wait) {
let timer = null;
let pre = 0;
return function () {
let now = Date.now();
if (now - pre > wait) {
if (timer) {
clearTimeout(timer)
timer = null
}
fn()
//记录最后一次触发时间
pre = now
} else if (!timer) {
//当前还不可触发,则缓存一次等触发.
timer = setTimeout(() => {
fn();
timer = null
pre = Date.now();
}, wait)
} else {
console.log(`此时,还在触发等待期,并且缓存中还有等执行,则啥也不做.`);
}
}
}
以下是完整html代码,可直接运行
<!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>
<div id="button" style="padding: 40px;background-color: aqua;cursor: pointer;">点我触发</div>
</body>
<script>
//节流 定时器 (最后一次也触发)
function throttle1(fn, wait) {
//弊端,第一下不会立即触发.
let timer = null;
return function () {
if (!timer) {
timer = setTimeout(() => {
timer = null;
fn()
}, wait);
}
}
}
//节流 时间戳 (第一次就触发)
function throttle2(fn, wait) {
//弊端,最后一下,并不会触发.
let pre = 0;
return function () {
let now = Date.now()
if (now - pre > wait) {
fn()
pre = now
}
}
}
//节流 控制最后一次和第一次
function throttle3(fn, wait) {
let timer = null;
let pre = 0;
return function () {
let now = Date.now();
if (now - pre > wait) {
if (timer) {
clearTimeout(timer)
timer = null
}
fn()
//记录最后一次触发时间
pre = now
} else if (!timer) {
//当前还不可触发,则缓存一次等触发.
timer = setTimeout(() => {
fn();
timer = null
pre = Date.now();
}, wait)
} else {
console.log(`此时,还在触发等待期,并且缓存中还有等执行,则啥也不做.`);
}
}
}
const func = throttle3(() => {
console.log('节流函数触发啦');
}, 1000);
document.querySelector('#button').addEventListener('click', () => {
console.log('用户点击了按钮');
func()
})
</script>
</html>
完