瀏覽器的scroll(滾動條滾動)、keypress(按動按鍵)、mousemove(滑鼠移動)等等事件在出發時,都是會不斷的呼叫系結在事件上的回呼函式高頻觸發,如果回呼函式復雜就會導致回應跟不上觸發,有可能會造成頁面的卡頓,極大地浪費資源,降低前端的性能,
對此有兩種解決方案:防抖(debounce ) 和 節流(throttling );
一、 防抖(debounce )
作用:是在短時間內多次觸發事件的回呼函式,只執行最后一次,或者只在最開始時執行,
以用戶拖拽改變視窗大小,觸發resize事件為例,在這程序中視窗的大小一致在改變,所以如果我們在resize事件中系結回呼函式,這個函式將會在拖拽的程序一直觸發,如果回呼函式過于復雜難免不會造成頁面卡頓,而且這種情況在多數情況下也是無意義的,還會造成資源的大量浪費,
普通方案:
window.addEventListener('resize',()=>{
console.log('觸發事件');
});
優化方案
function debounce(fn,delay){
// 維護一個 timer
let timer=null;
return function(){
// 獲取函式的作用域和變數
let context=this;
let args=arguments;
clearTimeout(timer);
timer=setTimeout(function(){
fn.apply(context,args);
},delay);
}
}
function res(){
console.log('觸發事件');
}
//在 debounce 包裝要觸發的函式,過1000秒觸發;
window.addEventListener('resize',debounce(res,1000));
代碼邏輯:
- 在resize事件上系結處理函式,這時debounce函式會立即呼叫,實際上系結的函式時debounce函式內部回傳的函式,
- 每一次事件被觸發,都會清除當前的timer定時器然后重新設定,到時間呼叫,
- 只有在最后一次觸發resize事件,才能在delay時間后執行,
添加引數,設定為立即執行函式
function debounce(fn,delay,rightAway=false){ //rightAway 不傳時 ,默認為非立即執行函式
// 維護一個 timer
let timer=null;
return function(){
// 獲取函式的作用域和變數
let context=this;
let args=arguments;
if(timer) clearTimeout(timer);
if(rightAway){
var now=!timer;
timer=setTimeout(()=>{
timer=null;
},delay);
if(now){
fn.apply(context,args);
}
}else{
timer=setTimeout(()=>{
fn.apply(context.args);
},delay);
}
}
}
二、節流(throttling )
作用:類似于防抖,不過節流是在一段時間之內只允許該函式執行一次
定時器實作
function throttle(fn,delay){
var timer =null;
return function(){
let context=this;
let args=arguments;
if(!timer){
timer=setTimeout(()=>{
fn.apply(context,args);
timer=null;
},delay);
}
};
}
function res(){
console.log('觸發事件');
}
window.addEventListener('resize',throttle(res,2000));
時間戳實作
function throttle(fn,delay){
var p =Date.now();
return function(){
let context=this;
let args=arguments;
let n=Date.now();
if(n-p>=delay){
fn.apply(context,args);
p =Date.now();
}
};
}
function res(){
console.log('觸發事件');
}
window.addEventListener('resize',throttle(res,2000));
以上兩重情況都是用于高頻觸發事件,根據不同場景選擇合適的用法,對于有停頓的高頻觸發事件建議選擇防抖,然而對于高頻觸發并且連續的事件,選擇節流,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/271365.html
標籤:其他
