debounce:持續觸發某一個事件的時候 好比持續觸發scroll的時候 函數是不執行的,當觸發結束後在settimeout delay後才執行函數; 這樣就避免了不斷地觸發app
/**ide
Parma:函數
func:觸發事件須要執行的函數;this
delay:延遲時間;.net
immediate:是否在尾部執行(注:此參數在delay很小的時候看不出效果,須要把 delay設置很大才能夠看出效果,此參數能夠省略)事件
**/rem
// immediate爲true的時候 表明當即執行 即距離上一次waite以後 下次滾動開始以前 // immediate爲false的時候 表明停頓waite後執行 // true鼠標動的時候執行 false鼠標動過以後又不動的時候執行 function debounce(func,wait,immediate){ var timeout; immediate || (immediate = true);//設置默認值 wait||(wait =20); return function(){ var context = this,args = arguments; var later = function(){ timeout = null; if(!immediate) func.apply(context,args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later,wait); if(callNow) func.apply(context,args) } } function checkSlide(e){ console.log(window.scrollY); } window.addEventListener('scroll',debounce(checkSlide));
throttle:每間隔一段時間內執行事件與debounce不一樣的是 不管事件是否持續 都是間隔一段時間當即執行的而debounce是等待持續事件停頓的間隔時間執行的get
/** *it
頻率控制 返回函數連續調用時,action 執行頻率限定爲 次 / delayio
* @param delay {number} 延遲時間,單位毫秒
* @param action {function} 請求關聯函數,實際應用須要調用的函數
* @param options? {leading:true,trailing:false} 第一次是否執行,默認爲true,表示第一次會執行,傳入{leading:false}則禁用第一次執行options.trailing:最後一次是否執行,默認爲true,表示最後一次會執行,傳入{trailing: false}表示最後一次不執行所謂第一次是否執行,是剛開始觸發事件時,要不要先觸發事件,若是要,則previous=0,remaining 爲負值,則當即調用了函數所謂最後一次是否執行,是事件結束後,最後一次觸發了此方法,若是要執行,則設置定時器,即事件結束之後還要在執行一次。remianing > wait 表示客戶端時間被修改過。
* @return {function} 返回客戶調用函數 *
/
function throttle(func, wait, options) { var context, args, result; var timeout = null; options ||(options ={leading:true,trailing:false});//默認參數 wait || (wait =1000); // 定時器 var previous = 0; // 上次觸發的時間 // if (!options) options = {}; var later = function() { previous = options.leading === false ? 0 : new Date(); timeout = null; result = func.apply(context, args); if (!timeout) context = args = null; }; return function() { var now = new Date(); // 第一次是否執行 if (!previous && options.leading === false) previous = now; console.log(previous); // 這裏引入了一個remaining的概念:還剩多長時間執行事件 var remaining = wait - (now - previous); console.log(remaining); console.log(now - previous); context = this; args = arguments; // remaining <= 0 考慮到事件中止後從新觸發或者 // 正好相差wait的時候,這些狀況下,會當即觸發事件 // remaining > wait 沒有考慮到相應場景 // 由於now-previous永遠都是正值,且不爲0,那麼 // remaining就會一直比wait小,沒有大於wait的狀況 // 估計是保險起見吧,這種狀況也是當即執行 if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout = null; } previous = now; result = func.apply(context, args); if (!timeout) context = args = null; // 是否跟蹤 } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } };};