学习目标
- 函数节流概念
- 函数节流的应用场景
- 函数节流实现
- 第三方库
定义
在单位时间内,只能触发一次函数。如果在这个单位时间内多次触发函数,都不会生效。 简单理解:就像王者荣耀里边,猴子的技能,你点了其中的一个技能,你就需要等待3秒,才能触发第二次。如果你在3秒内,又去点该技能,是不会生效的。
应用场景
- 鼠标不断点击触发,mousedown(单位时间内只触发一次),比如:表单提交
- 监听滚动事件,比如是否滑到底部自动加载更多
代码实现
- 时间差判断
触发事件时立即执行,以后每过delay秒之后才执行一次,并且最后一次触发事件若不满足要求不会被执行
function throttle(fn, delay) {
let prev = 0;
console.log(prev);
return function (...args) {// 函数的参数
const now = Date.now(); // 记录现在的时间
if(now - prev >= delay) { // 如果间隔时间大于等于设置的节流时间
console.log(1)
fn.apply(this, args); // 修改内部函数的this指向
prev = now;
}
}
}
- 定时器
第一次触发时不会执行,而是在delay秒之后才执行,当最后一次停止触发后,还会再执行一次函数。
function throttle(fn, delay) {
let timer = null;
return function(...args) {
if(!timer){
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
}
}
}
- 时间差和定时器结合
第一次会马上执行,最后一次也会执行
function throttle(fn,delay) {
let timer = null;
let prev = 0;
return function (...args) {
const now = Date.now();
// 触发间隔是否大于delay
let remaining = delay - (now - prev);
clearTimeout(timer);
if (remaining <= 0) {
fn.apply(this, args);
prev = Date.now();
} else {
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
}
第三方库
// 避免在滚动时过分的更新定位
jQuery(window).on('scroll', _.throttle(updatePosition, 100));
// 点击后就调用 `renewToken`,但5分钟内超过1次。
var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
jQuery(element).on('click', throttled);
// 取消一个 trailing 的节流调用。
jQuery(window).on('popstate', throttled.cancel);
var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);