防抖
- 觸發函數後多長時間沒再次觸發,執行一次函數,若是再次觸發從新開始計時
- 經常使用於 key resize 等高頻事件,輸入框輸入值時的本地緩存和異步請求
// 當頁面發生滾動的時1s後執行函數
var timer = null;
window.addEventListener('scroll', function() {
if(timer) clearTimeout(timer);
timer = setTimeout(function() {
console.log('我是a函數');
}, 1000)
});
// 把函數抽出來
var timeout = null;
function debounce() {
if(timeout) clearTimeout(timeout);
timeout = setTimeout(function() {
console.log('我是a函數');
}, 1000)
}
window.addEventListener('scroll', debounce);
// 消除全局變量timeout
function debounce(fn, delay) {
var timeout = null;
return function() {
if(timeout !== null) clearTimeout(timeout);
timeout = setTimeout(fn, delay);
}
}
function aa(){
console.log('我是a函數')
}
window.addEventListener('scroll', debounce(aa, 1000));
// 消除局部變量timeout
function debounce(fun, delay) {
return function() {
let that = this;
clearTimeout(fun.id)
fun.id = setTimeout(function() {
fun.call(that)
}, delay)
}
}
window.addEventListener('scroll', debounce(aa, 1000));
// es6語法 減小局部變量
function debounce(fun, delay) {
return function() {
clearTimeout(fun.id)
fun.id = setTimeout(() => {fun()}, delay)
}
}
window.addEventListener('scroll', debounce(aa, 1000));
//模擬一段ajax請求
function ajax(content) {
console.log('ajax request ' + content)
}
function debounce(fun, delay) {
return function (args) {
let that = this
let _args = args
clearTimeout(fun.id)
fun.id = setTimeout(function () {
fun.call(that, _args)
}, delay)
}
}
let inputb = document.getElementById('debounce')
// 變量賦值
let debounceAjax = debounce(ajax, 500)
inputb.addEventListener('keyup', function (e) {
debounceAjax(e.target.value)
})
節流
- 規定多少時間內執行一次函數
- 經常使用於click,scroll事件,監聽是否滑動到底部加載更多
- 節流實現的方式有兩種時間戳和定時器
// 1. 時間戳的方式 特色:第一次觸發 當即執行
var throttle = function(func, delay) {
var prev = Date.now();
return function() {
var that = this;
var args = arguments;
var now = Date.now();
if(now - prev >= delay) {
func.apply(that, args);
prev = Date.now();
}
}
}
function aa() {
console.log('我是aa函數');
}
window.addEventListener('scroll', throttle(aa, 1000));
// 2. 定時器方式 特色:第一次不會當即執行,最後一次會延遲執行
var throttle = function(func, delay) {
var timer = null;
return function() {
var that = this;
var args = arguments;
if(!timer) {
timer = setTimeout(function() {
func.apply(that, args);
timer = null;
}, delay);
}
}
}
function aa() {
console.log('我是aa函數');
}
window.addEventListener('scroll', throttle(aa, 1000));
// 3. 時間戳+定時器 第一次會當即執行,最後一次會延遲執行
var throttle = function(func, delay) {
var timer = null;
var startTime = Date.now();
return function() {
var curTime = Date.now();
var remaining = delay - (curTime - startTime);
var that = this;
var args = arguments;
clearTimeout(timer);
if(remaining <= 0) {
func.apply(that, args);
startTime = Date.now();
} else {
timer = setTimeout(func, remaining);
}
}
}
參考
掘金-7分鐘理解JS的節流、防抖及使用場景
節流
好理解es6