摘要:防抖和节流连续触发触发频率很高的时间,不进行优化,会出现页面卡顿现象。节流防抖是多次触发事件,目标函数只执行一次,不管触发这些事件用了多少时间。
防抖(debounce)和节流(throttle)
连续触发(触发频率很高)的时间,不进行优化,会出现页面卡顿现象。
常见的需要优化的事件:
鼠标事件:
mousemove(拖拽)
mouseover(划过)
mouseWheel(滚屏)
键盘事件:
keydown(按下键盘)
keypress(按下字符键盘)
keyup(弹起键盘)
window resize/scroll
DOM 元素动态定位
优化方式是控制事件处理器在一段时间内的执行次。
防抖频繁(连续)触发事件(比如用户触发输入事件input),不执行目标动作,当不在触发事件了,再执行。
实现思路,在事件处理器内,使用 setTimeout 包裹目标动作,一直触发事件,就清除上次的定时器,不再触发触发事件,会执行最后一个定时器,目标动作也执行一次了。
JS代码:
function debounce(callback, delay) { let timeout = 0; return e => { console.log("清除", timeout, new Date()); clearTimeout(timeout); //input 一直触发,就清除上一次的定时器,防止执行目标函数,直到事件不触发事件,最后一个定时器没有清除,delay 时间后就会执定时器,就确保了目标函数只执行一次。 timeout = setTimeout(() => { callback(e); }, delay); console.log("新的", timeout, e.target.value, new Date()); }; } let print = debounce(e => { let value = e.target.value; console.log(value, new Date()); }, 1000); document .querySelector("#input") .addEventListener("input", print, false);
清除定时器的时机很关键,在新定时器生成之前,如果在之后,会将所有定时器都清除,目标函数一次都不执行。
节流防抖是多次触发事件,目标函数只执行一次,不管触发这些事件用了多少时间。而节流是在一段时间内,确保目标函数只执行一次,实现缓慢执行目标函数的效果。
上面的输入使用节流实现:
let thorttle = (callback, delay) => { let timeout = 0; let now = new Date() - 0; return e => { console.log("now", now); let last = new Date() - 0; clearTimeout(timeout); if (last - now >= delay) { console.log("时间间隔", last - now); callback(e); now = last;//将上执行的时间赋值给 now } else { //将 delay 时间内多次触发事件,目标函数合并到这里执行 timeout = setTimeout(() => { callback(e); }, delay); } }; }; let write = thorttle(e => { console.log(e.target.value, new Date()); }, 5000); document .querySelector("#input") .addEventListener("input", write, false);两者比较
节流在某个时间段内,目标函数能执行一次,限制目标函数的执行频率,不管事件触发了多少次;
防抖是多次触发事件,目标函数只执行一次,不管触发了这些事件用了多少时间。
节流函数限制目标函数的执行频率,有连续变化的效果,适用于关注变化过程的操作,可以调整目标函数执行频率使得变化更加平滑,比如动画、改变窗口时执行某些操作等,常用事件resize、scroll、mouseWheel、touchmove、mouseover等;
防抖函数适用于更关注结果的操作,不太关注操作过程,常见的事件有 input、keyup等。
最后看一个 将 防抖 和 节流都用 resize 事件的效果,更能体会两者的区别:
function debounce(callback, delay) { let timeout = 0; return e => { clearTimeout(timeout); timeout = setTimeout(() => { callback(e); }, delay); }; } let print = debounce(e => { let value = e.target.value; console.log("debounce", window.innerWidth); }, 500); let thorttle = (callback, delay) => { let timeout = 0; let now = new Date() - 0; return e => { let last = new Date() - 0; clearTimeout(timeout); if (last - now >= delay) { callback(e); now = last; } else { timeout = setTimeout(() => { callback(e); }, delay); } }; }; let write = thorttle(e => { console.log("thorttle", window.innerWidth); }, 500); window.addEventListener("resize", write, false); window.addEventListener("resize", print, false);参考
函数节流与函数防抖
函数防抖与函数节流
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/104855.html
摘要:防抖和节流连续触发触发频率很高的时间,不进行优化,会出现页面卡顿现象。节流防抖是多次触发事件,目标函数只执行一次,不管触发这些事件用了多少时间。 防抖(debounce)和节流(throttle) 连续触发(触发频率很高)的时间,不进行优化,会出现页面卡顿现象。常见的需要优化的事件: 鼠标事件: mousemove(拖拽) mouseover(划过) mouseWheel(滚屏)...
摘要:防抖函数防抖和节流是一对常常被放在一起的场景。同时,这里会设置一个定时器,在等待后会执行,的主要作用就是触发。最后,如果不再有函数调用,就会在定时器结束时执行。 函数节流和去抖的出现场景,一般都伴随着客户端 DOM 的事件监听。比如scroll resize等事件,这些事件在某些场景触发非常频繁。 比如,实现一个原生的拖拽功能(不能用 H5 Drag&Drop API),需要一路监听...
摘要:相反,在讨论时,面试中通常会提到三件事。而认为最后一个参赛者说了算,只要还能吃的,就重新设定新的定时器。试想,如果用户的操作十分频繁他每次都不等设置的时间结束就进行下一次操作,于是每次都为该用户重新生成定时器,回调函数被延迟了不计其数次。本文不是讨论最新的 JavaScript 库、常见的开发实践或任何新的 ES6 函数。相反,在讨论 JavaScript 时,面试中通常会提到三件事。我自己...
阅读 2680·2021-11-22 13:52
阅读 1159·2021-10-14 09:43
阅读 3600·2019-08-30 15:56
阅读 2917·2019-08-30 13:22
阅读 3236·2019-08-30 13:10
阅读 1524·2019-08-26 13:45
阅读 1076·2019-08-26 11:47
阅读 2738·2019-08-23 18:13