JS函数防抖、节流

一 、什么是函数防抖

  对于短时间内连续触发的事件(onresizescrollmousemove ,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))

 

posted @ 2021-12-07 15:34  逩跑得前端小学生  阅读(88)  评论(0编辑  收藏  举报