//节流
let timer = null
document.onmousemove = function() {
console.log(timer,'-------------------');
if(timer !== null) return;
timer = setTimeout(()=>{
console.log('111');
timer = null
}, 1000)
}
首先要有一个模拟的场景,鼠标是在一直滚动的。
需求:在鼠标一直滚动的过程中,每隔一秒输出滚动条位置
节流代码:
function throttle(fn,delay){
console.log("只执行一次")
let valid = true
return function() {
console.log("滚轮滚动中",valid)
if(!valid){
return false
}
valid = false
setTimeout(() => {
fn()
valid = true; }, delay)
}
}
function showTop () {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
}
window.onscroll = throttle(showTop,1000)
执行结果:
代码详解:
window.onscroll = throttle(showTop,1000) ,将throttle函数的执行结果赋值给window.onscroll ,执行后
window.onscroll = function() {
console.log("滚轮滚动中",valid)
if(!valid){
return false
}
valid = false
setTimeout(() => {
fn()
valid = true;}, delay)
}
滚动鼠标滚轮时,调用上面的函数。
步骤1、第一次滚动(假设只触发一次函数):
此时valid = true,因为window.onscroll = throttle(showTop,1000),此时throttle被调用(仅被调用一次),执行了let valid = true。
然后接着执行:
valid = false
setTimeout(() => {
fn()
valid = true;}, delay)
}
步骤2、fn()函数要一秒后才执行,但是在此期间,鼠标是一直滚动的,然而valid = false,所以一直执行:
if(!valid){
return false
}
//可以理解成,滚轮在一直滚动,从而一直触发后面的函数,但是每触发一次,就因为valid = false而又马上退出了函数
步骤3、直到一秒之后,执行了:
fn()
valid = true;
此时,因为valid = true,所以再次执行:
又回到了步骤1
valid = false
setTimeout(() => {
fn()
valid = true;}, delay)
}
所以就是不断循环这个过程。