节流的应用场景:
1)滚动页面
如果在时间间隔内就不触发事件
如果不在时间间隔内就触发事件
即:
如果timer被赋值了,也就是等待任务执行中,暂时不改变timer值,直接return;
如果timer没有被赋值,那就给他赋值,执行任务,随后清空timer timer = null;
时间戳的写法:使用Date对象
1)定义pre变量,表示前一个时刻时间;
2)在执行函数中,获得当前时刻;
3)当前时刻 - 前一时刻,如果时间间隔大于设定值就执行函数;
4)考虑this指向和参数问题
function scroll() {
console.log('scroll')
}
// 1、基本结构
function throttle(fn) {
return function () {
fn()
}
}
// 2、设置定时
function throttle(fn, delay) {
return function () {
setTimeout(function () {
fn()
}, delay)
}
}
// 3、定时对象判断
function throttle(fn, delay) {
let timer
return function () {
// 如果timer有值,说明正在执行任务,则直接返回
if (timer) {
return
}
// 否则的话,就执行函数,并且将timer清空
timer = setTimeout(function () {
fn()
timer = null
}, delay)
}
}
// 解决this指向、参数问题
function throttle(fn, delay) {
let timer
return function () {
// 这两个获取一定在内部
let context = this
let args = arguments
if (timer) {
return
}
timer = setTimeout(function () {
fn.call(context, args)
}, delay)
}
}
window.addEventListener('scroll', throttle(scroll, 2000))
时间戳的写法:
function scroll() { console.log('scroll') } // 1、基本结构 function throttle(fn) { return function () { fn() } } // 2、设置定时 function throttle(fn, delay) { return function () { setTimeout(function () { fn() }, delay) } } // 3、时间戳 function throttle(fn, delay) { // 前一时刻 let pre = 0 return function () { // 当前时刻 let now = new Date() // 判断时间间隔 if (now - pre > delay) { setTimeout(function () { fn() }, delay) // 更新 pre pre = now } } } // 解决this指向、参数问题 function throttle(fn, delay) { let pre = 0 return function () { // 这两个获取一定在内部 let context = this let args = arguments let now = new Date() if(now - pre > delay){ setTimeout(function(){ fn.call(context, args) pre = now },delay) } } } window.addEventListener('scroll', throttle(scroll, 2000))