轉載:https://www.jianshu.com/p/518607d2f84b
防抖和節流-是針對響應跟不上觸發頻率這類問題的兩種解決方案
debounce,去抖動。策略是當事件被觸發時,設定一個週期延遲執行動作,若期間又被觸發,則重新設定週期,直到週期結束,執行動作。
debounce的特點是當事件快速連續不斷觸發時,動作只會執行一次。 延遲debounce,是在週期結束時執行。但當觸發有間斷,且間斷大於我們設定的時間間隔時,動作就會有多次執行。
//必須在動作停止後計時算再執行,防抖類似於事件結束回調
<div id="special">debounce</div>
<script>
var delay = 300;
var special = document.getElementById('special') // 獲取頁面的右邊
// 這是執行debounce的。
window.onresize = function () {
debounce(addlist, delay); //這一個設置
}
function debounce(fn, delay) { // 定義一個debounce函數
if(fn.timeid)clearTimeout(fn.timeid);
//清除時間戳(有才能清除
fn.timeid = setTimeout(function () {
fn();
}, delay)//延遲一段時間執行addlist
}
function addlist() { // 監聽事件的響應事件,執行dom操作。
special.innerHTML += '<li>k+</li>'
}
</script>
繼續思考,使用上面的防抖方案來處理問題的結果是: 如果在限定時間段內,不斷觸發滾動事件(比如某個用戶閒着無聊,按住滾動不斷的拖來拖去),只要不停止觸發,理論上就永遠不會輸出當前距離頂部的距離。
throttle節流:節流與抖動不一樣,節流是會說預先設定一個執行週期,當調用動作的時刻大於等於執行週期則執行該動作,然後進入下一個新週期。拿onscroll事件來說,如果使用的是抖動的話,只用當滾動停止後纔會執行回調函數,在滾動的過程是不會執行的。節流不同,滾動的時候每隔一個時間週期就會執行一次回調,然後進入下一個新週期
原理:節流函數不管事件觸發有多頻繁,都會保證在規定時間內一定會執行一次真正的事件處理函數。
節流類似技能冷卻時間
<div id="common">throttle</div>
<script>
var delay = 300;
var common = document.getElementById('common') // 獲取頁面的左邊
function commonWay() { // 這是執行了普通的函數
common.innerHTML += '<li>k</li>'
}
// tottle的實現,也就是節流的實現,就是設置了一個一開始函數運行的時間戳進行執行
var startTime=0,//開始時間
timestamp,//當前時間
timer;//定時器
function throttle(fn, delay) {
timestamp =+new Date(); // 獲取當前時間
if (timestamp - startTime >= delay) {
//如果現在-開始>=延遲時間就執行
fn();
startTime = timestamp;
}
}
window.addEventListener('resize', function () {
throttle(commonWay, 1000);
})
</script>