这是我参与8月更文挑战的第16天,活动详情查看:8月更文挑战
问题起源
页面中常见的监听浏览器滚动事件,窗口的 onresize 事件以及输入框实时监听输入事件都会导致这些事件会被高频触发,而如果此类事件的执行函数比较复杂,响应跟不上事件的触发的话,就会导致页面卡顿假死的现象,从而让用户体验非常糟糕,浏览器的性能是有限的,不应该浪费在这里,所以就出现了函数防抖(debounce)和函数节流(throttling)的策略
问题的解决方案
函数防抖(debounce):当事件触发时,设定一个周期延迟执行动作,如果期间再次触发,则重新设定周期,知道周期结束才执行动作。前缘防抖:执行动作在前,然后设定周期,周期内有事件被触发,不执行动作,且周期重新设定。函数节流(throttling):固定周期内,只执行一次动作,若有新事件触发,不执行。周期结束后,又有事件触发,开始新的周期。 注:延迟:周期结束后执行动作; 前缘:执行动作后再开始周期
应用场景
函数防抖(debounce):事件触发是高频次但是有停顿,如: 页面 resize 事件函数节流(throttling):事件连续不断高频触发时, 如: 监听浏览器滚动事件
实现方法
// 函数防抖,如果短时间内大量触发同一事件,只会执行最后一次函数
function debounce(fn, wait) {
var timer = null;
return function() {
if (timer) clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, Array.prototype.slice.call(arguments, 0)), wait);
}
}
// 函数节流,如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效
function throttle(fn, wait) {
var timer = null;
return function() {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, Array.prototype.slice.call(arguments, 0));
timer = null;
}, wait);
}
}
}
(求关注)
欢迎关注我的公众号:A纲 Coder,获得日常干货推送。最后再次感谢您的阅读,我是程序猿憨憨