JS(12),详细介绍并手写防抖和节流函数

1、闭包的应用:防抖和节流

1.1、防抖(debounce):

  • 当连续触发使事件时,一段时间内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前又一次触发事件,就重新开始延时
  • 可以理解为“回城”,回城固定时间是8秒,要是在这个过程中有人打断你,你就要重新开始回城
  • 步骤:
  • 1、我们首先需要触发事件(当页面中的事件触发时,就会触发addEventListener里面的函数)
  • 2、这时我们便重置计时单位,然后开始计时
  • 3、如果在一定时间范围了没有再次触发,便执行函数
  • 4、如果在一定范围内有再次触发,便再次重置计时单位,再次开始计时
  • 防抖函数实例如下
<script>
    const btn = document.querySelector('button')

    //处理函数
    function pay() {
        console.log('触发');
    }

    function myDebounce(fun, delay) {
    //首先判断fun是否为函数
        if(typeof fun !== 'function'){
            console.error('type error');
            return
        }

        //设置一个计时timer,该timer会被后面函数引用,形成闭包
        let timer

         return function () {
            //原来fun事件的this是指向页面中的标签的
            //但是在后面回调的时候,fun函数运行在window下,所以this指向window
            //这时候就要先记录this的,在后面再改回来
            let context = this
            let args = arguments
            clearTimeout(timer)
            timer = setTimeout(function () {
                fun.apply(context,args)
            }, delay)
        }
    }
        
    //触发事件
    btn.addEventListener('click', myDebounce(pay, 500))
</script>

1.2、节流(throttle)

  • 当持续触发事件时,保证一定时间内只调用一次事件处理函数。
  • 可以理解为技能的CD,比如吕布一技能的cd是5秒,就算持续按一技能,吕布也只能每隔5秒释放一次一技能。
  • 步骤:
  • 1、触发事件的时候马上执行任务,然后设定时间间隔限制
  • 2、在这段时间内无论用于怎么触发事件,都忽略操作
  • 3、在时间到了以后,如果用户再次触发事件,便子啊此执行任务,然后设置时间间隔
  • 两种方法
  • (1)、定时器
<script>
        const btn = document.querySelector('button')

        function pay() {
            console.log('已剁手');
        }

        function myThrottle(fun, delay) {
            //首先判断fun是否时函数
            if (typeof fun !== 'function') {
                console.error('type error');
                return
            }

            //设置一个计时timer
            let timer
            return function(){
                let context = this
                let args = arguments
                //如果timer被赋值了,也就是任务还在等待执行,暂时不改变timer的值
                //如果timer没有被赋值,那就给它赋值执行任务就好了
                if(timer){
                    return
                }
                timer = setTimeout(function(){
                    fun().apply(this,args)
                    timer = null
                },delay)
            }
        }
        btn.addEventListener('click', myThrottle(pay, 500))
</script>

  • (2)、时间戳
<script>
        const btn = document.querySelector('button')

        function pay() {
            console.log('已剁手');
        }

        function myThrottle(fun, delay) {
            //首先判断fun是否时函数
            if (typeof fun !== 'function') {
                console.error('type error');
                return
            }

            let pre = 0;
            return function(){
                let context = this
                let args = arguments
                let now = new Date()
                if(now - pre >= delay){
                    fun.apply(context,args)
                    pre = now
                }
            }
            
        }
        btn.addEventListener('click', myThrottle(pay, 500))
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值