防抖
- 触发函数后多长时间没再次触发,执行一次函数,如果再次触发重新开始计时
- 常用于 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的节流、防抖及使用场景
节流
好理解