函数防抖
事件被触发后,在一定时间内再次触发,则以后一次触发为标准重新计算时间,直到这段时间内没有二次触发,才执行。
1、无防抖代码
//html代码
<input id="unDebounce">
//script代码
//模拟一段ajax请求
function ajax(content) {
console.log('ajax request ' + content)
}
let inputa = document.getElementById('unDebounce')
inputa.addEventListener('keyup', function (e) {
ajax(e.target.value)
})
没有防抖的情况下,输入框每输入一个单词,就会请求一次,浪费时间,效率低
打印结果如下:
2、加入防抖函数
//html代码
<input id="debounce"/>
//script代码
//模拟一段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)
})
加入防抖后,当你在输入框频繁输入时, 并不会连续发送请求。
只有当你在指定间隔时间内没有输入时,才会执行函数。也就是在keyup触发一定时间内没有再次触发,就会发送请求。
打印结果如下:
函数节流
在一段时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有第一次生效。
例1:频繁点击事件触发
不断点击页面,一段时间内只触发一次
function throttle(fn, delay) {
var timer;
return function () {
var _this = this;
var args = arguments;
if (timer) {
return
}
timer = setTimeout(function () {
fn.apply(_this, args);
timer = null;
}, delay)
}
}
function testThrottle(e, content) {
console.log(e, content);
}
var testThrottleFn = throttle(testThrottle, 1000); // 节流函数
document.onmousemove = function (e) {
testThrottleFn(e, 'throttle'); // 给节流函数传参
}
可看到,这段代码中清除定时器的时间与防抖不同。
防抖在执行时会先清除定时器,因为在规定时间内二次触发后会以后一次触发为标准重新计时。
节流则是判断是否有定时器,没有定时器就创建定时器执行,有定时器就用return阻止执行,直到前一次的执行完成,清除定时器,进行下一次的执行。这样就能在规定时间内只执行一次,规定时间内的其他触发无效。
例2: 时间戳实现节流函数
function throttle(fn,delay){
var previous = 0;
// 使用闭包返回一个函数并且用到闭包函数外面变量previous
return function(){
var _this = this;
var args = arguments;
var now = new Date();
if(now - previous > delay){
fn.apply(_this,args);
previous = now;
}
}
}
function testThrottle(e,content){
console.log(e,content);
}
var testThrottleFn = throttle(testThrottle,1000);
document.onmousemove = function(e){
testThrottleFn(e,'throttle')
}
原理:与前一次触发时间相比,如果时间差大于了延迟时间则触发。
运用场景
debounce
- search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
- window触发resize时,不断调整浏览器窗口大小会不断触发事件,让防抖来让其触发一次
throttle
- 鼠标不断的点击事件,mousedown(单位时间只触发一次)
- 监听滚动事件,比如是否滑到底部自然加载更多