js高级进阶之函数防抖、截流

在前端开发实现相关功能时,由于js中部分事件的设计存在一定的问题,对完成业务带来很大的困难,比如js的scrooll ,mouseover ,resize等事件浏览器是实时触发实时相应的,那么如果我们要对其进行监听实现相关业务,那么就会导致业务也被连续多次执行

看个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        #content{
            width: 400px;
            height: 400px;
            background-color: bisque;
            word-break: break-all;
        }
    </style>
</head>
<body>
    <div id = "content"></div>
</body>
<script>
    let e = document.getElementById("content");
    e.addEventListener("pointermove",function(){
        e.innerHTML += "c"
    })
</script>
</html>

此时如果鼠标放在div区域内不停移动,则监听事件就会不停执行。我们当然不希望如此频繁执行。就需要做节流处理。

防抖和节流概念

防抖:抖动停止后的时间超过设定的时间时执行一次函数。注意:这里的抖动停止表示你停止了触发这个函数,从这个时间点开始计算,当间隔时间等于你设定时间,才会执行里面的回调函数。如果你一直在触发这个函数并且两次触发间隔小于设定时间,则一定不会到回调函数那一步。

节流:按照设定的时间固定执行一次函数。

区别:防抖着重于处理连续不间隔触发,给定时间限制后只有大于这个时间限制的连续操作才会执行,而节流是无论连续操作多少次(时间)只有在固定时间间隔采取执行。

使用场景
防抖:input验证、resize
节流:scroll、mousemove

我们将上面的示例用节流方法进行改造

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        #content{
            width: 400px;
            height: 400px;
            background-color: bisque;
            word-break: break-all;
        }
    </style>
</head>
<body>
    <div id = "content"></div>
</body>
<script>
    let e = document.getElementById("content");
    let fn = function(){
        e.innerHTML += "c"
    }
   
    function throttle(fn,delay=100){
        let last = 0;
        return function(){
            let curr = +new Date();
            if(curr - last > delay){
                fn.apply(this,arguments);
                last = curr;
            }
        }
    }
    e.addEventListener("pointermove",throttle(fn,500));

</script>
</html>

防抖改造:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        #content{
            width: 400px;
            height: 400px;
            background-color: bisque;
            word-break: break-all;
        }
    </style>
</head>
<body>
    <div id = "content"></div>
</body>
<script>
    let e = document.getElementById("content");
    let fn = function(){
        e.innerHTML += "c"
    }

    //防抖
    function debounce(fn, delay, atBegin = true) {
        let timer = null, last = 0,during;
        return function () {
            let self = this, args = arguments;
            var exec = function () {
                fn.apply(self, args);
            }
            if (atBegin && !timer) {
                exec();
                atBegin = false;
            } else {
                during = Date.now() - last;
                if (during > delay) {
                    exec();
                } else {
                    if (timer) clearTimeout(timer);
                    timer = setTimeout(function () {
                        exec();
                    }, delay);
                }
            }
            last = Date.now();
        }
    }
    e.addEventListener("pointermove",debounce(fn,500));
</script>
</html>

防抖函数时间戳经典实现

function debounce(fn, delay, atBegin = true) {
        let timer = null, last = 0,during;
        return function () {
            let self = this, args = arguments;
            var exec = function () {
                fn.apply(self, args);
            }
            if (atBegin && !timer) {
                exec();
                atBegin = false;
            } else {
                during = Date.now() - last;
                if (during > delay) {
                    exec();
                } else {
                    if (timer) clearTimeout(timer);
                    timer = setTimeout(function () {
                        exec();
                    }, delay);
                }
            }
            last = Date.now();
        }
    }

节流函数时间戳经典实现

function throttle(fn,delay=100){
        let last = 0;
        return function(){
            let curr = +new Date();
            if(curr - last > delay){
                fn.apply(this,arguments);
                last = curr;
            }
        }
    }

本篇博文参考了http://caibaojian.com/throttle-debounce.html
感谢作者的分享,对作者表示敬意!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值