今天使用原生js时碰到一个需求:点击按钮调用接口获取数据并跳转页面,但是为了防止按钮的多次被点击导致接口一直被调用的问题,整理了一些防抖和节流的代码
1.原生js实现防抖
**什么是防抖?**
事件触发后,若n秒内该事件没有再次发生,则执行这个函数,如果n秒内该事件再次发生,则重新开始计时。
//防抖 事件不立即触发,N秒内只能被触发一次
let btn = document.querySelector('button');
function write(){
console.log('已经成功实现防抖');
}
const fd = function(fn,deplay){
let timer;
return function(){
const that = this;
const arg = arguments;
clearTimeout(timer);
timer = setTimeout(function(){
fn.apply(that,arg)
},deplay)
}
}
btn.addEventListener('click',fd(write ,1000));
2.原生js实现节流
**什么是节流 ?**
节流当指定时间持续触发某个事件时,该事件只会执行首次触发事件,
也就是说指定时间内只会触发一次。
原生实现节流的方式有两种:定时器节流(不会立即触发)和时间戳节流(立即触发)
//定时器节流 (不会立即触发) ---- 个人不建议使用
//不立即触发,N秒内只能被触发一次
const btn = document.querySelector('button');
function write() {
console.log('这是定时器节流');
}
const jl = function (fn, deplay) {
let timer;
return function () {
let content = this;
let ar = arguments;
if (timer) {
return;
}
timer = setTimeout(function () {
fn.apply(content, arguments);
timer = null;
}, deplay);
}
}
btn.addEventListener('click', jl(write, 1000));
//时间戳节流(立即触发) --- 推荐使用
//立即触发,但下次允许触发在N秒后(N秒内无法被触发)
let btn = document.getElementById("btn")
function write() {
console.log('这是时间戳节流');
}
function throttle(fn, waiting) {
// 上一次的执行时间
let previous = 0;
return function (...args) {
// 当前时间
let now = +new Date();
if (now - previous > waiting) {
previous = now;
fn.apply(this, args);
}
}
}
btn.addEventListener('click', throttle(write, 1000));