这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
之前项目中有一个需求,点击底部提交按钮调用接口只能调用一次,不能多次点击调用否则会频繁触发接口,当时首先想到的就是防抖或是节流,虽然后来发现在这个功能里并不适合用防抖或是节流,但是因为我对这块也不是很了解,所以学习后就在这里记录一下,以便以后查阅。
防抖
概念:当事件被频繁触发时,只在最后一次触发的n秒后调用(即在当前的时间里只调用一次)
使用场景: input 输入搜索
思路:
使用setTimeout方法,每次输入的时候如果时间间隔到了n秒则直接调用ajax方法,否则就clearTiemout,一直等到n秒再调用方法。
// 防抖
let setTimeoutFn = null;
function debounceFn(fn, delay) {
return () => {
if (setTimeoutFn) clearTimeout(setTimeoutFn);
setTimeoutFn = setTimeout(fn, delay);
}
}
const debonceDom = document.getElementById('debonceDom');
function debounceAjaxFn() {
const debounceInput = document.getElementById('debounceInput');
debounceInput.innerHTML = debonceDom.value;
}
debonceDom.addEventListener('keyup', debounceFn(debounceAjaxFn, 2000));
PS:这里我很想弄个动图,可以直观的看到效果,但是我搞了半天还是没弄出来o(╥﹏╥)o,暂时弄个图片凑活看吧☺
节流
概念:当事件被频繁触发时,每隔n秒调用(在频繁触发的时间里可能调用多次)
使用场景:同上
思路: 还是使用setTimeout方法,不过是在方法里面清空延迟以达到每隔n秒调用的效果
// 节流
function throttleFn(fn, delay) {
let times = null;
return () => {
if (!times) {
times = setTimeout(() => {
fn.apply(this, arguments);
times = null; // 在延迟方法里把该方法置空,这也是和防抖的主要区别
}, delay);
}
}
}
const throttleDom = document.getElementById('throttleDom');
function throttleAjaxFn() {
const throttleInput = document.getElementById('throttleInput');
throttleInput.innerHTML = throttleDom.value;
}
throttleDom.addEventListener('keyup', throttleFn(throttleAjaxFn, 2000));
总结
防抖和节流我觉得都可以在像input输入、鼠标悬浮、滚轮滚动和窗口size更改等状态下使用,就看想要哪种效果啦。