防抖与节流

1.防抖:

防抖是指在事件触发n秒后再执行回调,如果在n秒内再次被触发,则重新计算时间。(就是在触发某个事件后,在下一次触发之前,中间的间隔时间如果超过设置的时间才会发送请求,一直触发就不会发送请求)

前面的所有的触发都被取消,最后一次执行在规定的时间之后才会触发,也就是说连续快速的触发 只会执行一次。通过setTimeout的方式限制函数的执行次数,在一定的时间间隔内,将多次触发变成一次触发

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="submit" id="input">

</body>
</html>
<script>
    let btn = document.getElementById('input')
    // btn.addEventListener('click',submit,false)
    btn.addEventListener('click',debounce(submit),false)

    function debounce(func,delay,immediate) {
        let timer = null
        /*
        * 存在两个问题
        * 1.当前的事件对象如何获取
        * 2.this如何处理*/
        //debounce要返回一个函数 点击btn 由window调用该函数
        //返回的函数就是点击按钮后window调用的函数 会传递一个事件参数,但是我们不能直接传个e 因为我们目前不知道传参的个数是多少
        //当不知道传入参数的个数时 是不能用形参来获取当前的参数列表
        //这里我们使用arguments
        return function() {
            //这里的this是指向input
            console.log(this)
            console.log(arguments[0])
            //当用户多次点击时,定时器就会存在多个 下面if判断 只要存在定时器就会清除重新生成
            //多次点击只会执行一次 就实现了防抖的效果
            if(timer){
                clearTimeout(timer)
            }
            //问题:当我们第一次点击的时候 也执行了延时处理
            //解决
            if(immediate){
                //判断是不是第一次 timer = null时
                /*
                * 注:一般涉及到null判断时 会把null写成布尔值
                * 原因:undefined == null 可能还会造成错误判断*/
                let firstClick = !timer /*timer为null !timer为布尔值true*/
                if(firstClick) {
                    func.apply(this, arguments)
                }
                timer = setTimeout(() =>{
                    timer = null
                },delay)
            }else {
                //限制func的执行
                timer = setTimeout(()=> {
                    //每一个实参列表对应自己内部的函数 这里的实参是定时器函数的 与外层函数的不是同一个
                    /*
                    * 改变实参指向两种方法
                    * 1.用赋值方式
                    * 2.用箭头函数 将内部的arguments指向改成外部函数的arguments指向*/
                    console.log(arguments[0])
                    //这里的this拿的是箭头函数外部的this
                    func.apply(this,arguments)
                }, delay)
            }
        }
    }

    function submit(e){
        //如果是没有包装之前的函数
        //btn.addEventListener('click',submit,false)
        //这里的this指向input
        console.log(this)
        //此时的事件参数e为MouseEvent
        console.log(e)
    }
    function debounce(fn,delay,immediate) {
        return function () {
            let timer = null
            let firstClick = !timer
            if(timer){
                clearTimeout(timer)
            }
                //判断是不是第一次点击
            if(firstClick){
                fn.apply(this,arguments)
            }
            setTimeout(()=>{
                timer = null
            },delay)
        }

    }

</script>

2.节流:

在规定的间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="submit" id="input">

</body>
</html>
<script>
    let btn = document.getElementById('input')
    // btn.addEventListener('click',submit,false)
    btn.addEventListener('click',debounce(submit),false)

    function submit(e){
        //如果是没有包装之前的函数
        //btn.addEventListener('click',submit,false)
        //这里的this指向input
        console.log(this)
        //此时的事件参数e为MouseEvent
        console.log(e)
    }

    function throttle(fun,delay) {
        //第一次点击的时间
        let begin =0
        return function () {
            //获取当前时间戳
            let cur = new Date().getTime()
            //当前点击与上一次点击的时间差
            if(cur - begin > delay){
                fun.apply(this.arguments)
                begin = cur
            }


        }

    }


</script>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值