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 分钟前
# JS 核心六大主题:闭包内存模型、原型链查找、事件流机制与 Promise / Event Loop 实现视角复盘
前端·javascript
gis开发之家1 小时前
vue3直击架构痛点 依赖倒置与接口隔离——打造坚如磐石的插件与高阶组件(HOC)模式
javascript·架构·typescript·前端框架·vue3
柒和远方1 小时前
LeetCode 139. 单词拆分 —— 从暴力回溯到 DP 完全背包
javascript·python·算法
先吃饱再说1 小时前
流式输出完全指南:让 AI 对话像打字机一样流畅
javascript·vue.js
এ慕ོ冬℘゜3 小时前
原生 JS 实现自定义单选日历组件(无 UI 库、纯手写、禁用过去日期)
开发语言·javascript·ui
mONESY4 小时前
Skill 技能与 MCP 协议的底层逻辑与协同真相
javascript
南川琼语4 小时前
HTTP——AJAX
前端·javascript·ajax
不简说5 小时前
JS 代码技巧 vol.2 — 20 个数组/对象/字符串/正则的实用技巧
前端·javascript·面试
小小编程路5 小时前
C++ 块作用域详解:从基础到实战
前端·javascript·vue.js
虚惊一场5 小时前
MarkView:纯前端 Markdown 实时预览工具的架构设计
前端·javascript·vue.js