14 # 手写 debounce 防抖方法

什么是防抖

防抖: n 秒后再去执行该事件,若在 n 秒内被重复触发,则重新计时,这个效果跟英雄联盟里的回城技能差不多。

本质上是优化高频率执行代码的一种手段,目的就是降低回调执行频率、节省计算资源。

应用场景:

  • 搜索框搜索输入,手机号、邮箱等验证输入检测,只需用户最后一次输入完,再发送请求
  • 窗口大小 resize,只需窗口调整完成后,计算窗口大小,防止重复渲染。
html 复制代码
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>防抖</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/underscore.js/1.13.6/underscore-min.js"></script>
    </head>
    <body>
        <div>
            普通输入框:
            <input class="input1" />
        </div>
        <div>
            防抖输入框:
            <input class="input2" />
        </div>
        <script>
            // 普通
            const inputEl1 = document.querySelector(".input1");
            let counter1 = 1;
            inputEl1.oninput = function () {
                console.log(`发送网络请求${counter1++}`, this.value);
            };
            // 防抖处理过的
            const inputEl2 = document.querySelector(".input2");
            let counter2 = 1;
            inputEl2.oninput = _.debounce(function () {
                console.log(`防抖处理:发送网络请求${counter2++}`, this.value);
            }, 1000);
        </script>
    </body>
</html>

手写 debounce

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>手写防抖</title>
    <script>
        function kaimoDebounce(fn, delay) {
            let timer = null;
            let _debounce = function (...args) {
                // 清除上一次定时器
                clearTimeout(timer);
                // 开启新的一个定时器
                timer = setTimeout(() => {
                    // this 和参数绑定
                    fn.apply(this, args);
                    // 函数执行完之后,将timer置为null
                    timer = null;
                }, delay);
            };
            return _debounce;
        }
    </script>
</head>

<body>
    <div>
        防抖输入框:
        <input class="input" />
    </div>
    <script>
        const inputEl = document.querySelector(".input");
        let counter = 1;
        inputEl.oninput = kaimoDebounce(function (e) {
            console.log(`手写防抖:发送网络请求${counter++}`, this, this.value);
            console.log(e);
        }, 1000);
    </script>
</body>

</html>
相关推荐
独隅1 小时前
WebStorm Windows 版 React / Next.js 实战替换指南
javascript·windows·webstorm
冷眸_1 小时前
同名食材不能直接相减:一个 JavaScript 用量模型的边界
javascript
apollo_qwe1 小时前
接口超时了,前端为什么不能直接重试?
javascript·http
toooooop86 小时前
CRMEB 故障排查笔记:安全网关只放行 GET/POST 怎么办
前端·javascript·vue.js·thinkphp6·crmeb
软件技术NINI6 小时前
基于SpringBoot和Vue的项目评审系统
javascript·vue.js·spring boot·后端·spring·毕业设计·毕设
vipxieliang6 小时前
JavaScript 模板字符串与标签模板:不只是拼接
前端·javascript
Dream-Y.ocean17 小时前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
Highcharts.js18 小时前
Highcharts Gantt使用符号的自定义数据标签开发甘特图示例
javascript·甘特图·highcharts·图表开发·实战代码·响应式图表
kyriewen21 小时前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
工控丫丫21 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库