JS深入之防抖(debounce)

参考文章
github上冴羽的博客
函数节流
节流

什么是防抖(debounce)

在进行窗口的resize、scroll,输入框内容校验等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕。此时我们可以采用debounce(防抖)throttle(节流) 的方式来减少调用频率,同时又不影响实际效果。

防抖原理

你尽管触发事件,但是我一定在事件停止触发 n 秒后才执行。
这意味着如果你在一个事件触发的 n 秒内又触发了这个事件,那我就以新的事件触发的时间为准,在此时间 n 秒后才执行。
简单的说,当一个动作连续触发,则只执行最后一次。
打个比方,坐公交,司机需要等最后一个人进入才能关门。每次进入一个人,司机就会多等待几秒再关门。

防抖的应用场景

连续的事件,只需触发一次回调的场景有:
1.搜索框搜索输入。只需用户最后一次输入完,再发送请求
2.手机号、邮箱验证输入检测
3.窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。

小例子

防抖的关键是使用 setTimeout(function(){},) 来实现

非立即执行函数版: 触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

function debounce(func, wait) {
    let timeout;
    return function () {
        let context = this;
        let args = arguments;

        if (timeout) clearTimeout(timeout);
        
        timeout = setTimeout(() => {
            func.apply(context, args)
        }, wait);
    }

立即执行函数版:触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。

<body>
    <div id="container"></div>
    <script>
        var count = 1;
        var container = document.getElementById('container');

        function getUserAction() {
            container.innerHTML = count++;
        };
// 我不希望非要等到事件停止触发后才执行,我希望立刻执行函数,然后等到停止触发 n 秒后,才可以重新触发执行
// immediate 参数判断是否是立刻执行
       function debounce(func, wait, immediate) {

            var timeout, result;

            return function () {
//使用这两行代码来获取 this 和 参数,是为了让 debounce 函数最终返回的函数 this 指向不变以及依旧能接受到 e 参数。
                var context = this;
                var args = arguments;

                if (timeout) clearTimeout(timeout);
                if (immediate) {
                    // 如果已经执行过,不再执行
                    var callNow = !timeout;
                    timeout = setTimeout(function(){
                        timeout = null;
                    }, wait)
                    if (callNow) result = func.apply(context, args)
                }
                else {
                    timeout = setTimeout(function(){
                        func.apply(context, args)
                    }, wait);
                }
                return result;
            }
        }
        //移动完后1000秒调用
        container.onmousemove = debounce(getUserAction, 1000);
    </script>
</body>

鼠标移动上去后 移开1000ms后++ 不管移动多少次 都是不移动后1000ms才++

交流群 626319356

我作为一个小白,因为个人兴趣自学前端 后端。在学习的道路上独自一人前行,没啥钱也没报啥班,所以想要有共同理想的道友让我们互帮互助,共同成长。
建群目的
各种学习资料共享
各种学习导图共享
如何学习前端 后端 指点 少走弯路
遇到问题 互相解决 吸取经验
声明
因为自己是个菜鸡 大三非计算机专业 对应专业知识比较薄弱
所以这个群的主要目的是互相成长
如果有大佬愿意帮助我们
我在此表示感谢
欢迎各位道友加入

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值