前端防抖与节流

在某些高频度触发的事件中绑定操作需要用到节流函数。

函数防抖

最常见的打个栗子,如果要在window的滚动事件中发送ajax请求加载更多数据。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body{
            height: 1200px;
            background-color: lightblue;
        }
    </style>
</head>
<body>
   
</body>
<script >
    window.addEventListener("scroll",function(){
        // 这里发送ajax请求,这里用console.log(1)来代替一下
        console.log(1)
    })
</script>
</html>

有需要的童鞋可以把此段复制到html文件中自行查看效果。

我们来看看此时页面的表现效果。

此时我们可以看到console.log(1)被高频度触发。如果此时scroll里面触发的是ajax请求,那么在页面滚动的一小段时间内,就会发送45次ajax请求。性能开销不容小觑。

对此问题,封装节流函数如下  

function throttle(fn,time){
        return function(){
            clearTimeout(fn.tId)
            fn.tId = setTimeout(fn,time)
        }
    }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body{
            height: 1200px;
            background-color: lightblue;
        }
    </style>
</head>
<body>
   
</body>
<script >
    function throttle(fn,time){
        return function(){
            clearTimeout(fn.tId)
            fn.tId = setTimeout(fn,time)
        }
    }
    window.addEventListener("scroll",throttle(function (){console.log(1)},1000))
</script>
</html>

此时再来看看页面表现

防抖函数的实现原理,throttle函数第一个参数为要执行的函数,第二个参数为间隔时间。那么如何理解这个间隔时间呢。

假设我们在滚动时触发了100次滚动事件,那么就执行了100次throttle函数,第一次执行throttle,清除定时器。然后设置定时器。此时的console.log(1)会在1s之后执行,但是此时执行了第二次throttle函数,它又清除了第一个定时器。生成了第二个定时器。。。。。。,到最后执行第一百次throttle函数,他清除了第99个定时器,设置第一百个定时器。此时throttle全部执行完成,console.log(1)会在1s之后执行。

那么可以这样理解。throttle的第一个参数为待执行函数,第二个参数为停止滚动后几秒内执行函数。上述栗子中的throttle(function(){console.log(1)},1000)表示停止滚动后1s内执行console.log(1)。同时表示着,如果你停止滚动后,在1s内再次滚动,待执行函数也不会执行。它严格执行条件为停止滚动,1s内。

函数节流

那么函数防抖有什么缺陷,从它的实现原理来看它的缺陷也是显而易见的。

比如我滚动页面要看看更多内容,用户肯定是希望边滚动边浏览到更多信息,到自己感兴趣的地方再停下来。函数节流的缺陷在于如果用户一直滚动,那么页面就一直不会刷新。对此我们需要更加人性化的函数节流来实现此效果。它会给用户操作添加一个最小时间片。待执行时间每隔最小时间片就会执行一次。它不会有原生scroll那么高的执行频率,同时也没有防抖函数那么僵硬。

同时它内部也使用到了防抖函数,可以说是防抖pro版本。

贴上代码。供童鞋们自行参悟其中奥妙。

 const debounce = (realFn, timer = 200) => {
        return (event) => {
            if (!realFn.tid) {
                realFn.tid = setTimeout(() => {
                    realFn(event)
                    clearTimeout(realFn.tid)
                    realFn.tid = null
                }, timer)
            }
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值