一 、什么是函数防抖
对于短时间内连续触发的事件(onresize,scroll,mousemove ,mousehover ),触发事件后 n 秒内函数只能执行一次,如果触发事件后 n 秒内又触发了事件,则重新计算函数延执行时间
二、如何解决
setTimeout 辅助实现,延迟运行需要执行的代码;
三、具体代码
// 防抖 短时间内多次触发同一事件,只执行最后一次,或者只执行最开始的一次,中间的不执行。
/**
* @desc 函数防抖
* @param fn目标函数
* @param delay 延迟执行
* @param {Object} immediate
*/
function debounce(fn, delay, immediate) {
if(typeof fn != "function") {
throw new TypeError("fn不是函数")
}
let timer;
return function() {
var _this = this
var args = arguments
if(timer) {
clearTimeout(timer)
}
if(immediate) { // 立即执行(触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数)
let callnow = !timer
timer = setTimeout(() => {
timer = null
}, delay)
if(callnow) fn.apply(_this, args)
} else { // 延迟执行(触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间)
timer = setTimeout(function() {
fn.apply(_this, args);
}, delay)
}
}
}
input.addEventListener('keyUp', debounce(() => {
console.log(input.value)
}, 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))