JS - 函数防抖 & 函数节流
函数节流
限制一个函数在一定时间内只能执行一次(无论触发多少次,也都是每n秒后才执行一次)
主要用来防止频繁触发,优化程序性能,提高体验等等
方法一:时间戳
这个方法通过判断两次获取时间间隔长短来判断是否执行函数
每次触发时,只要到达指定时间点就会立即执行
触发函数后立即执行,等待n秒后才执行第二次
var $button1 = document.getElementById('button1');
var num = 0;
$button1.addEventListener('click', throttle(throttleCallback, 1000));
function throttle(callBack, waitTime) {
var time = Date.now();
return function() {
var nowTime = Date.now();
var that = this;
var args = arguments;
/// 时间间隔判断
if ( nowTime-time >= waitTime ) {
callBack.apply(that, args);
// 触发方法后更新点击时间
time = Date.now();
} else {}
}
}
// 执行函数
function throttleCallback(e) {
e.stopPropagation(); // 取消事件冒泡
num++;
console.log(num);
}
方法二:定时器
这个方法通过设置定时器延时执行函数
每次触发时,需要到指定时间后才执行
触发函数后不立即执行,等待n秒后才执行函数
var $button2 = document.getElementById('button2');
var num = 0;
$button2.addEventListener('click', DispatcherTimer(DispatcherTimerCallBack, 1000));
function DispatcherTimer(callBack, waitTime) {
var timer = null;
var wait = 200; // 保存时间变量, 为了让第一次点击时能立即执行
return function() {
var that = this;
var grgs = arguments;
// 判断是否存在定时器
if(!timer) {
timer = setTimeout(function(){
callBack.apply(that, grgs);
// 执行后清除定时器
clearTimeout(timer);
timer = null;
}, wait);
} else {}
wait = waitTime; // 保存延迟时间
}
}
// 执行函数
function DispatcherTimerCallBack(e) {
e.stopPropagation();//取消事件冒泡
num++;
console.log(num);
}
鼠标事件节流
window.addEventListener('mousemove', moveThrottle(moveThrottleCallBack, 1000));
function moveThrottle(callBack, waitTime) {
var timer = null;
return function() {
var grgs = arguments;
// 判断是否存在定时器
if(!timer) {
timer = setTimeout(()=>{
callBack.apply(this, grgs);
// 执行完成后清除定时器,等待下一次执行
clearTimeout(timer);
timer = null;
}, 1000);
}
}
}
// 执行函数
function moveThrottleCallBack(e){
console.log('鼠标事件节流');
}
函数防抖
当持续触发事件时,一定时间内没有再触发事件,事件函数才会执行一次。当在设定的时间之内又触发了事件函数,就会重新开始计时
既是在一些高频触发事件里,但其实只需要生效一次即可的函数,无论触发多少次,值运行最后一次
var $button3 = document.getElementById('button3');
$button3.addEventListener('click', debounce(function(){
console.log("点击事件 函数防抖")
}, 500));
function debounce(fn, waitTime) {
var timer = null;
return function() {
var that = this;
// 每次触发先清除定时器,再重新计算时间
clearTimeout(timer);
timer = null;
timer = setTimeout(function(){
fn.call(that);
}, waitTime);
}
}
鼠标事件
var t = null; // 定时器
window.addEventListener('mousemove', moveDebounce);
function moveDebounce(e){
// 每次触发先清除定时器,再重新计算
clearTimeout(t);
t = null;
t = setTimeout( ()=>{ move(e) }, 300 )
}
function move(e) {
console.log('鼠标事件防抖');
}
滚动事件
var t = null;// 定时器
window.addEventListener('scroll', scrollDebounce);
function scrollDebounce(e) {
// 每次触发先清除定时器,再重新计算
clearTimeout(t);
t = null;
t = setTimeout( () => { scrollF(e) }, 300 );
}
function scrollF(e) {
console.log("滚动事件");
}