JS函数防抖、节流
一 、什么是函数防抖
对于短时间内连续触发的事件(onresize,scroll,mousemove ,mousehover ),触发事件后 n 秒内函数只能执行一次,如果触发事件后 n 秒内又触发了事件,则重新计算函数延执行时间
二、如何解决
setTimeout 辅助实现,延迟运行需要执行的代码;
三、具体代码
1 // 防抖 短时间内多次触发同一事件,只执行最后一次,或者只执行最开始的一次,中间的不执行。 2 /** 3 * @desc 函数防抖 4 * @param fn目标函数 5 * @param delay 延迟执行 6 * @param {Object} immediate 7 */ 8 function debounce(fn, delay, immediate) { 9 if(typeof fn != "function") { 10 throw new TypeError("fn不是函数") 11 } 12 13 let timer; 14 return function() { 15 var _this = this 16 var args = arguments 17 if(timer) { 18 clearTimeout(timer) 19 } 20 21 if(immediate) { // 立即执行(触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数) 22 let callnow = !timer 23 timer = setTimeout(() => { 24 timer = null 25 }, delay) 26 if(callnow) fn.apply(_this, args) 27 } else { // 延迟执行(触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间) 28 timer = setTimeout(function() { 29 fn.apply(_this, args); 30 }, delay) 31 } 32 } 33 } 34 35 input.addEventListener('keyUp', debounce(() => { 36 console.log(input.value) 37 }, 600))
四、什么是节流
函数执行一次之后,该函数在指定的时间期限内不再工作,直到过了这段时间才重新生效
五、适用场景
搜索框搜索输入、改变浏览器窗口大小
六、代码实现
1 // 节流 2 /** 3 * @param {Object} 函数节流 4 * @param {Object} delay 5 * @param {type} 1 表时间戳版,2 表定时器版 6 * 时间戳版的函数触发是在时间段内开始的时候,而定时器版的函数触发是在时间段内结束的时候 7 */ 8 function throttle(fn, delay, type) { 9 if (type === 1) { 10 let previous = 0; 11 } else if (type === 2) { 12 let timer; 13 } 14 return function() { 15 var _this = this; 16 var args = arguments; 17 if(type === 1) { 18 let now = Date.now(); 19 if (now - previous > delay) { 20 fn.apply(_this, args) 21 previous = now 22 } 23 } else if(type === 2) { 24 if(timer) { 25 return 26 } 27 timer = setTimeout(function() { 28 fn.apply(fn, args) 30 timer = null // 在delay后执行完fn之后清空timer,此时timer为假,throttle触发可以进入计时器 31 }, delay) 32 } 33 } 34 } 35 36 diva.addEventListener('drgs', throttle((e) => { 37 console.log(e.offsetX, e.offsetY) 38 }, 100))
认真做事儿,踏实做人