节流
-
原理: 事件触发后,规定时间内,事件处理函数不能再次被调用。也就是说在规定时间内,函数只能被调用一次,而且是最先被触发调用的那次。
-
使用场景: 高频率的点击事件、选择器的联想输入、列表页面滚动加载更多等等。。。
方法一
/**
* fn 需要节流的函数 delay 间隔时间
*/
function throttle (fn, delay) {
// 记录上次触发的时间
let lastTime = 0;
return function() {
// 记录当前函数触发的时间
let nowTime = Date.now()
// 如果 (当前时间)- (上次触发时间) > 设定的间隔时间
if(nowTime -lastTime > delay) {
//修正this指向问题
fn.call(this);
// 同步执行介绍的时间
lastTime = nowTime
}
}
}
方法二
/**
* fn 需要节流的函数 delay 间隔时间
*/
function throttle (fn, delay) {
// 设置一个用来判断是否可以执行的变量
let flag = true;
return function() {
if(!flag) return false; // 如果为false就不往下执行
// 刚开始 flag 为 true,不会进入return, 然后将 flag 设置为 false,进入定时器,
// 在设置的定时器的时间间隔过了之后才会把 flag 设置会 true, 只有 flag 为 true 时才能再次执行事件函数
flag = false
setTimeout(()=> {
fn.apply(this, arguments)
flag = true
}, delay)
}
}
使用案例
function submit() {
console.log("提交了")
}
doucument.getElementById("submitBtn").onClick = throttle(submit(), 500)
防抖
-
原理: 多次触发事件,事件处理函数只能执行一次,并且是在触发操作结束时执行,也就是说,当一个事件被触发准备执行函数前,会等待一定的时间,如果没有再次被触发,那么就执行,如果被触发了,那就作废本次,重新从新触发的时间开始计算,再次等待设定的时间,直到最终执行。
-
使用场景: 输入框输入后验证身份证号,手机号,邮箱等。。。
/**
* 一个需要频繁触发的函数,在规定时间内,只能让最新的一次触发生效,之前的都作废
* fn 要被节流的函数 delay 规定的时间
*/
function debounce(fn, delay) {
// 记录上一次的延时器
let timer = null
return function () {
// 清除上一次的延时器
clearTimeout(timer);
// 重新设置新的延时器
timer = setTimeout(function() {
// 修正this指向问题
fn.apply(this)
}, delay)
}
}
document.getElementById('btn').onclick = debounce(function() {
console.log('按钮点击了')
}, 1000)
借鉴的原文文档链接: 前端必备八股文 - 丹青-水墨 - 博客园 (cnblogs.com)