JS防抖:别再让按钮“手抖”连点了!

你有没有遇到过这种情况:点击"提交订单"按钮,因为网络卡了点了两下,结果生成了两个订单?或者搜索框输入时,每输一个字就发一次请求,服务器直接"累到罢工"?这时候,JS防抖(Debounce)就能派上大用场了!

什么是防抖?

简单来说,防抖就是让函数"冷静"一下再执行。如果在短时间内频繁触发同一个函数,防抖会忽略前面的触发,只执行最后一次。就像你在电梯里按关门键,只要有人不断按,电梯就会一直等,直到没人按了才关门。

为什么需要防抖?

  • 减少请求次数:搜索框输入时,防抖可以等用户输入完成后再发请求,而不是每输一个字就发一次,大大减轻服务器压力。
  • 避免重复操作:按钮点击时,防抖可以防止用户快速连点导致的重复提交(比如下单、支付)。
  • 提升性能:对于一些复杂的DOM操作(比如窗口 resize 时计算元素位置),防抖可以避免频繁计算,让页面更流畅。

防抖函数怎么写?(超简单版)

下面是一个基础版的防抖函数,代码不多,注释也写得很清楚:

javascript 复制代码
 // 防抖函数:func是要执行的函数,delay是延迟时间(毫秒)
function debounce(func, delay) {
  let timer = null; // 定时器ID

  // 返回一个新函数
  return function(...args) {
    // 如果定时器存在,清除它(取消上一次的延迟执行)
    if (timer) clearTimeout(timer);

    // 重新设置定时器,delay毫秒后执行func
    timer = setTimeout(() => {
      func.apply(this, args); // 执行原函数,并传递参数
    }, delay);
  };
}

实际例子:按钮防抖

假设我们有一个"提交订单"按钮,点击后会调用 submitOrder() 函数。如果用户快速点击多次,就会重复提交。我们用防抖来解决这个问题:

html 复制代码
<button id="submitBtn">提交订单</button>
<script>
// 模拟提交订单的函数
function submitOrder() {
  console.log("订单提交成功!");
  // 这里可以写真实的接口请求代码
}

// 使用防抖包装submitOrder,延迟500毫秒执行
const debouncedSubmit = debounce(submitOrder, 500);

// 给按钮绑定点击事件,触发防抖后的函数
document.getElementById("submitBtn").addEventListener("click", debouncedSubmit);
</script>

现在,即使你在500毫秒内点击10次按钮,也只会执行一次 submitOrder() ,完美解决了重复提交的问题!

实际例子:搜索框防抖

再来看一个搜索框的例子。用户输入时,我们希望等用户停止输入1秒后,再发送搜索请求:

html 复制代码
<input type="text" id="searchInput" placeholder="请输入关键词搜索">

<script>
// 模拟搜索接口请求
function search(keyword) {
  console.log(`正在搜索:${keyword}`);
  // 这里可以写真实的搜索接口请求代码
}

// 使用防抖包装search,延迟1000毫秒执行
const debouncedSearch = debounce(search, 1000);

// 给搜索框绑定输入事件
document.getElementById("searchInput").addEventListener("input", function(e) {
  debouncedSearch(e.target.value); // 传递输入框的值给搜索函数
});
</script>

现在,用户输入"手机"时,不会每输一个字就搜索一次,而是等用户停止输入1秒后,才会执行一次搜索,大大减少了请求次数。

防抖的小细节

  • 延迟时间的选择:延迟时间(delay)要根据实际场景调整。按钮防抖一般用300-500毫秒,搜索框防抖一般用500-1000毫秒。
  • 立即执行:有时候我们希望第一次触发时立即执行,之后才防抖(比如按钮点击后立即禁用,防止重复点击)。这种情况可以给防抖函数加一个 immediate 参数,稍微修改一下代码即可实现(进阶需求,基础版暂时用不到)。

总结

记住这个简单的防抖函数,下次遇到"手抖"问题时,直接拿来用就可以啦!需要我帮你写一个带"立即执行"功能的进阶版防抖函数吗?

相关推荐
用户938515635076 小时前
从零在浏览器里跑 DeepSeek-R1:WebGPU + Transformer.js 全链路实战
前端·设计模式·typescript
CodeSheep6 小时前
稚晖君公司人事大变动,来了!
前端·后端·程序员
鱼樱前端7 小时前
用 AI 做内容变收入
前端·人工智能·ai编程
eric-sjq7 小时前
10 分钟实战:用 0.6B 本地模型生成中文网页(WanlyFrontend + 编译器全流程)
javascript·机器学习·自然语言处理·html
浮生望7 小时前
React + TypeScript 组件设计进阶:从类型约束到无状态组件的三次进化
前端
To_OC7 小时前
LC 438 找到所有字母异位词:暴力超时后,我靠滑动窗口一招搞定
javascript·算法·leetcode
90后的晨仔7 小时前
Mac 开发 uni-app 终极方案:让安卓模拟器彻底脱离 Android Studio 独立运行
前端·vue.js
90后的晨仔8 小时前
别再搞混了!uni-app 中 node_modules 和 uni_modules 到底是什么关系?
前端
kyriewen8 小时前
面试官问"这段逻辑为什么这样写"——我才发现,这半年我写的代码,我自己都解释不了
前端·javascript·面试
谢小飞9 小时前
大文件上传很难?学会这招,GB文件秒传不是梦
前端·node.js