防抖
简单版本的实现
function debounce(func, delay) {
let timeout;
return function() {
let context = this;//保存this的指向
let args = arguments; // 保存event对象
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, delay)
}
}
防抖如果需要立即执行,可加入第三个参数用于判断,实现如下
function debounce(func, delay, immediate) {
let timeout;
return function() {
let context = this;//保存this的指向
let args = arguments; // 保存event对象
if(timeout) clearTimeout(timeout); // timeout 不为null
if(immediate){
let callNow = !timeout; //第一次会立即执行,以后只有事件执行后才会再次触发;
timeout = setTimeout(() => {
timeout = null;
}, delay)
if(callNow) {
func.apply(context, args);
}
} else {
timeout = setTimeout(() => {
func.apply(context, args);
}, delay)
}
}
}
节流
完成节流可以使用时间戳与定时器的写法;使用时间戳写法,事件会立即执行,停止触发后没有办法再次执行;
function throttled(fn,delay = 500) {
let oldTime = Date.now();
return function(...args) {
let newTime = Date.time();
if(newTime - oldTime >= delay){
fn.apply(null, args);
oldTime = Date.now();
}
}
}
使用定时器写法,delay毫秒后第一次执行,第二次事件停止触发后依然会再一次执行
function throttled(fn,delay = 500) {
let timer = null;
return function(...args) {
if(!timer){
timer = setTimeOut(() => {
fn.apply(this, args);
timer = null;
}, delay)
}
}
}