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 参数,稍微修改一下代码即可实现(进阶需求,基础版暂时用不到)。

总结

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

相关推荐
晚夏_八月2 小时前
ES6 模块导出 export default 与 export 的区别?
前端
皮蛋瘦肉粥_1212 小时前
pink老师html5+css3day09
前端·css3·html5
Mintopia2 小时前
🧠 可定制化 AIGC:Web 用户个性化模型训练的技术门槛正在塌缩!
前端·人工智能·trae
JarvanMo2 小时前
Flutter CI/CD 完整指南:从 Bitbucket Pipelines 到 Play Store 自动化部署
前端
工业甲酰苯胺2 小时前
TypeScript 中的单例模式
javascript·单例模式·typescript
nvd113 小时前
Lit.js 入门介绍:与 React 的对比
开发语言·javascript·react.js
JarvanMo3 小时前
Flutter3.38 带来了什么
前端
倚栏听风雨3 小时前
React中useCallback
前端
不说别的就是很菜3 小时前
【前端面试】前端工程化篇
前端·面试·职场和发展