核心是禁用按钮+修改文字+定时器更新,点击即设disabled=true、启动setinterval每秒减1并更新innertext,倒计时归零时clearinterval并恢复按钮状态。

点击后按钮变灰并显示倒计时
核心是禁用按钮 + 修改文字 + 定时器更新。直接操作 disabled 属性和 innerText 即可,不需要额外 DOM 重绘或框架介入。
常见错误是只改文字不设 disabled,导致用户重复点击;或者用 setTimeout 递归但没清定时器,造成内存泄漏或多次触发。
- 初始按钮需有明确的
id(如sendBtn)或通过 class 选取 - 倒计时用
setInterval,每次减 1,到 0 时清除定时器、恢复按钮状态 - 务必在点击事件里立刻禁用按钮:
btn.disabled = true - 注意浏览器对快速连续点击的响应:加防抖不如直接禁用更可靠
JavaScript 实现 60 秒倒计时的最小可行代码
下面这段可以直接粘贴进 <script></script> 标签运行,兼容所有现代浏览器:
const btn = document.getElementById('sendBtn');
let timer = null;
let count = 60;
btn.addEventListener('click', () => {
if (timer) return; // 防重复绑定或触发
btn.disabled = true;
btn.innerText = `${count}秒后重发`;
timer = setInterval(() => {
count--;
btn.innerText = `${count}秒后重发`;
if (count
<p>注意:<code>count</code> 是闭包变量,每次点击都应重置为 60;如果按钮被禁用期间页面刷新,倒计时不会自动恢复——这是预期行为,服务端必须控制真实发送频次。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill9263" title="Html2md"><img
src="https://img.php.cn/upload/skill/000/000/081/179249945220127.jpg" alt="Html2md" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill9263" title="Html2md" class="overflowclass">Html2md</a>
<p class="overflowclass">使用 Readability + Turndown 将 HTML 页面转换为干净的、Agent 友好的 Markdown。去除导航栏、广告、页脚、Cookie 横幅、社交按钮等干扰元素。支持 URL...</p>
</div>
<a rel="nofollow" href="/xiazai/skill9263" title="Html2md" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<h3>为什么不能只靠前端倒计时防刷</h3>
<p>前端倒计时只是体验优化,<strong>完全不可信</strong>。用户可以禁用 JS、修改 DOM、甚至直接调接口。</p>
- 服务端必须校验同一手机号/邮箱的请求间隔(如 Redis 记录上一次发送时间)
- 前端倒计时结束 ≠ 允许发送,仍需服务端返回
200并携带新验证码才真正成功 - 若服务端拒绝发送(如频率超限),前端要根据响应恢复按钮,不能只依赖定时器
移动端点击无反馈?加 touchstart 兼容
iOS Safari 和部分安卓 WebView 对 click 事件有 300ms 延迟,导致按钮点击后视觉反馈滞后。解决方案是监听 touchstart 并阻止默认行为:
btn.addEventListener('touchstart', (e) => {
e.preventDefault();
// 然后触发你的发送逻辑或倒计时启动
}, { passive: false });
更稳妥的做法是同时绑定 click 和 touchstart,并在两个事件里共用同一套倒计时逻辑。别忘了在倒计时结束时移除 touchstart 监听器,避免内存残留。
实际项目中容易忽略的是:按钮文案在不同语言/屏幕宽度下可能换行或溢出,建议用 white-space: nowrap 和固定宽高保一致性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










