JS函数防抖、节流

一 、什么是函数防抖

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值