1.原理瀏覽器
事件頻繁觸發的狀況下,只有觸發的間隔超過指定間隔時,任務纔會執行。bash
(大白話就是,你儘管觸發事件,可是我必定在事件觸發 n 秒後才執行,若是你在一個事件觸發的 n 秒內又觸發了這個事件,那我就以新的事件的時間爲準,n 秒後才執行)閉包
export const Debounce = (func, wait) => {
var wait = wait || 200;
var timeout;
return function () {
/*
1.將this指向正確的對象。
使用debounce函數時,打印this會指向Window對象,
因此用context綁定上下文
*/
var context = this;
/*
2.arguments:將不肯定的變量替換到函數中了。
Eg:在test()方法中,因爲咱們不肯定變量有多少,好比
test("古天樂", "太陽才能黑的男人"),
又或者 test("渣渣輝", [1, 2, 3], 10),
這時候只須要在函數 test 中用 arguments 接收就好了。
*/
var args = arguments;
// 三、每次當用戶點擊/輸入的時候,把前一個定時器清除
clearTimeout(timeout)
// 四、建立一個新的 setTimeout,
這樣能保證點擊按鈕後的timeout間隔內若是用戶還點擊了的話,
就不會執行 fn 函數
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
複製代碼
// 防抖的應用。
methods:{
onClick:Debounce(function(){
...
}, 1000)
}
複製代碼
還有一種場景,點擊事件後馬上執行,等到中止觸發 n 秒後,才能夠從新觸發執行。app
export const Debounce = (func, wait, immediate) = {
var timeout;
return function () {
var context = this;
var args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) {
// 若是已經執行過,再也不執行
var callNow = !timeout;
timeout = setTimeout(function(){
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
}
複製代碼
當即執行的使用場景:函數
持續觸發事件,每隔一段時間,只執行一次事件。ui
關於節流的實現,有兩種實現方式,一種是使用時間戳,一種是設置定時器。this
/*
當觸發事件的時候,咱們取出當前的時間戳,
而後減去以前的時間戳(最一開始值設爲 0 ),
若是大於設置的時間週期,就執行函數,而後更新時間戳爲當前的時間戳,
若是小於,就不執行。
*/
export const throttle = (func, wait) => {
var context, args;
var previous = 0;
return function() {
var now = +new Date();
context = this;
args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
複製代碼
// 節流的應用。
methods:{
onClick:Debounce(function(){
...
}, 1000)
}
複製代碼
/*
當觸發事件的時候,咱們設置一個定時器,
再觸發事件的時候,若是定時器存在,就不執行,
直到定時器執行,而後執行函數,
清空定時器,這樣就能夠設置下個定時器。
*/
function throttle(func, wait) {
// 一、經過閉包保存一個標記
var timeout;
return function() {
context = this;
args = arguments;
// 二、在函數開頭判判定時器是否存在,存在則中斷函數
if (!timeout) {
timeout = setTimeout(function(){
//三、執行完事件(好比調用完接口)以後,從新將這個標誌設置爲null
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
複製代碼
節流的應用場景spa
- 懶加載要監聽計算滾動條的位置,使用節流按必定時間的頻率獲取
- 用戶點擊提交按鈕,假設咱們知道接口大體的返回時間的狀況下,
咱們使用節流,只容許必定時間內點擊一次。
複製代碼
主要涉及到瀏覽器渲染頁面的機制雙向綁定
// 具體信息本身額外補充吧
- 瀏覽器解析 URL
- 重繪與迴流複製代碼