一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Bootstrap怎么让按钮在加载状态时禁用并显示旋转图标

时间:2026-07-09 11:14:51 编辑:袖梨 来源:一聚教程网

必须用 button.disabled = true 禁用按钮,因其能真正阻止点击、键盘操作和表单序列化;配合 spinner-border 插入、finally 统一恢复状态、同步处理 aria-disabled 和 tabIndex,并缓存原始文案。

必须用 button.disabled = true,不是加 disabled

Bootstrap 5 不再响应 class="disabled" 来真正禁用按钮——它只改样式,不拦点击、不阻键盘(空格/回车)、不防表单序列化。你看到按钮变灰了,但用户仍能连点、Tab 过去按回车提交。唯一可靠方式是直接操作原生属性:button.disabled = truebutton.setAttribute('disabled', '')。浏览器会自动触发 button:disabled 样式规则(包括 opacity: .65pointer-events: none),语义、视觉、行为才一致。

旋转图标要用 spinner-border 插入 DOM,别靠伪元素或 CSS 动画

伪元素旋转(::after { animation: spin })容易导致文字偏移、按钮宽度跳变,尤其在小尺寸按钮里;纯 CSS 动画也难控制尺寸和居中。Bootstrap 5 自带的 spinner-border 更稳妥:

  • 插入前先清空按钮内容:button.innerHTML = ''
  • 创建并插入:const spinner = document.createElement('span');,设 className = 'spinner-border spinner-border-sm',加 role="status"aria-hidden="true"
  • 再追加文案:button.insertAdjacentText('beforeend', '提交中')
  • 避免多次点击后 DOM 嵌套爆炸(比如 <span><span><span>...

状态恢复必须写在 finally 块里,且要成套还原

只在 .then() 里恢复,接口返回 400/500 就卡死;只在 .catch() 里恢复,成功后反而漏掉。正确姿势是请求链末尾统一清理:

  • .finally(() => { button.removeAttribute('disabled'); button.textContent = originalText; })
  • 别用 button.disabled = false——某些旧环境不触发样式重绘
  • 若用了 AbortControllerfinally 里也要调 abortController.abort()
  • 同步清除 aria-disabledtabIndex:禁用时设 aria-disabled="true"tabIndex = -1,还原时移除并设回 tabIndex = 0

移动端和读屏器需要额外加固

部分安卓 WebView 和老版 Safari 对 disabledpointer-events 拦截不彻底,手指轻点可能穿透到背后元素;NVDA + Firefox 等读屏器有时不播报纯 disabled 状态。所以还得补两笔:

  • 禁用时:button.setAttribute('aria-disabled', 'true')button.tabIndex = -1button.style.pointerEvents = 'none'
  • 还原时:button.removeAttribute('aria-disabled')button.tabIndex = 0button.style.pointerEvents = ''
  • 若仍有点击穿透,临时加 button.style.position = 'relative' 防止层叠错乱

最易被忽略的是:原始文案必须提前缓存(比如存到 dataset.originalText),否则还原时图标或空格会被清掉;还有就是按钮类型得是 type="button",否则在表单内会默认触发表单提交,导致逻辑执行两次。

热门栏目