js 防抖和节流
防抖:N秒时间内高频率触发只执行一次,N秒内如果再次触发,则时间重置重新计算(使用场景:比如input输入框)
节流:N秒时间内无论事件触发多少次,只执行一次,节流相当于稀释了函数执行频率(使用场景:比如浏览器页面窗口调整大小)
防抖和节流都是限制函数的执行频率,优化函数执行次数避免高频率触发事件导致页面延迟、卡死和卡顿问题。
1、防抖input
window.onload = function () { function debounce(fn,delay) { var timeout = null; // 创建一个标记用来存放定时器的返回值 return function () { // 每当用户输入的时候把前一个 setTimeout clear 掉 clearTimeout(timeout); // 然后又创建一个新的 setTimeout, 这样就能保证interval 间隔内如果时间持续触发,就不会执行 fn 函数 timeout = setTimeout(() => { fn.apply(this, arguments); }, delay); }; } // 处理函数 模拟ajax function handle(content) { console.log('防抖:',content); } var inputDebounce = document.getElementById('debounce'); var debounceAjax = debounce(handle,500); inputDebounce.addEventListener('keyup', function (e) { debounceAjax(e.target.value); }) }
<div> 1.加入防抖后的输入: <input type="text" name="debounce" id="debounce"> </div>
2、节流resize
window.onload = function () { function throttle(fn,delay) {
let canRun = true; // 通过闭包保存一个标记
return function () { // 在函数开头判断标记是否为true,不为true则return if (!canRun) return; // 立即设置为false canRun = false; // 将外部传入的函数的执行放在setTimeout中 setTimeout(() => { // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。 // 当定时器没有执行的时候标记永远是false,在开头被return掉 fn.apply(this, arguments); canRun = true; }, delay); }; } function sayHi(content) { console.log('节流:', arguments); } var proresize = throttle(sayHi,5000); window.addEventListener('resize', function(e){ //throttle(sayHi,5000); proresize(e.target.innerWidth, e.target.innerHeight); }); }
总结:
防抖:延迟时间内执行的多次事件也就是多次操作合并成一次执行,在延迟时间内操作取消前面一次计时器重新设置,触发最后一次。
节流:延迟时间内无论触发执行多少次事件都将并一次执行,使用最多的比如用户滚动无限加载,用户在滚动加载数据,是在滚动的过程中根据延迟时间获取一次数据,一直滚动一直加载,相比滚动到底部停下操作加载数据体验感更好。