JavaScript防抖与节流 举个例子,在浏览器窗口的resize、scroll、input框内容校验等操作时,如果事件处理函数调用的频率无限制,就会加重浏览器的负担,造成异常现象,影响用户体验,这时就可以采用debounce和throttle的方式来减少调用频率,达到预期效果。
防抖debounce
定义:对于短时间内连续触发的事件,比如滚动事件,防抖就是让某个时间期限内,事件处理函数只执行一次。 关于防抖,拿手指按压弹簧举例,用手指按压弹簧,一直按住,弹簧将不会弹起直到松开手指。 举例resize:
function debounce(fn, wait){
var timer = null;
return ()=>{
if(timer !== null){
clearTimeout(timer);
}
timer = setTimeout(fn, wait);
}
}
function handle(){
console.log(Math.random());
}
window.addEventListener("resize",debounce(handle, 1000));
上面是非立即执行版 立即执行版
function debounce(fn, wait){
let timeid, flag = true;
return () => {
clearTimeout(timeid);
if(flag){
fn();
flag = false;
}else{
timeid = setTimeout(()=>{
flag = true;
}, wait);
}
}
}
拖动浏览器窗口,触发resize,此时并不触发handle函数,定时器计时,在计时时间内再次触发resize的话,则会从新计时,这样做的好处就是拖动浏览器窗口触发resize,并不会频繁执行handle函数,只让其在需要执行的时候去运行,有效的去除了冗余。 常见写法:
const debounce = (func, delay = 200) => {
let timeout = null
return function () {
clearTimeout(timeout)
timeout = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
节流throttle
定义:让事件在一定时间内只执行一次。 本意是像水龙头的水滴一样,规定时间内只执行一次,减少频繁反复执行。 如搜索框input事件。 通过时间戳计算:
function throttle(fn,wait){
let startTime = 0;
return function(){
let endTime = Date.now();
if(endTime-startTime>wait){
fn();
startTime = endTime;
}
}
}
通过定时器:
function throttle(fn,wait){
let timeid = null;
return function(){
if(!timeid){
timeid = setTimeout(function(){
fn();
timeid = null;
},wait)
}
}
}
|