Bootstrap 5 Modal加载Spinner在XMLHttpRequest完成后无法隐藏求助
问题分析与解决方案
你的问题根源有两个:
- Modal实例重复创建:每次调用
new bootstrap.Modal(...)都会生成全新的Modal实例,请求完成时调用的hide()是针对新实例的,而非之前显示的那个,因此无法隐藏已弹出的Modal。 - 请求地址不完整:
google.com是相对路径,实际会请求当前域名下的google.com资源而非谷歌官网,导致请求大概率失败,status == 200的条件永远不满足,hide()代码根本没执行。
原生JS修正方案
提前创建Modal实例并复用,同时修正请求地址,优化事件监听逻辑:
// 提前获取Modal元素并创建实例,仅执行一次 const loadingModal = new bootstrap.Modal(document.getElementById("loading"), { backdrop: 'static', keyboard: false }); const xhttp = new XMLHttpRequest(); // 使用loadstart和load事件替代onreadystatechange,逻辑更直观 xhttp.addEventListener('loadstart', () => { loadingModal.show(); }); xhttp.addEventListener('load', () => { if (xhttp.status === 200) { loadingModal.hide(); // 此处可添加请求成功后的业务逻辑 } else { // 请求失败时也要隐藏Modal,避免一直阻塞页面 loadingModal.hide(); console.error('请求失败,状态码:', xhttp.status); } }); // 处理请求异常情况 xhttp.addEventListener('error', () => { loadingModal.hide(); console.error('请求发生错误'); }); // 使用完整URL发起请求 xhttp.open("GET", "https://www.google.com", true); xhttp.send();
HTML部分保持不变(若需要可移除内联样式,改用自定义CSS类):
<!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap 5 Example</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js"></script> </head> <body> <div class="modal" style="background: none !important;" id="loading" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"> <div class="modal-dialog modal-dialog-centered" style="background: none !important;"> <div class="modal-content" style="background: none !important; border: none;"> <div class="modal-body" style="background: none !important; text-align: center;"> <div class="spinner-border text-primary" role="status"> <span class="visually-hidden">Loading...</span> </div> </div> </div> </div> </div> </body> </html>
jQuery版本(可选)
若你习惯用jQuery,代码可简化为:
$(document).ready(function() { const $loadingModal = $('#loading'); const loadingModal = new bootstrap.Modal($loadingModal[0], { backdrop: 'static', keyboard: false }); $.ajax({ url: 'https://www.google.com', type: 'GET', beforeSend: function() { loadingModal.show(); }, success: function() { loadingModal.hide(); }, error: function() { loadingModal.hide(); console.error('请求失败'); } }); });
关键注意事项
- 必须复用同一个Bootstrap Modal实例,禁止在事件回调中重复创建。
- 务必处理请求的所有异常场景(失败、网络错误),确保Modal最终会隐藏,避免页面永久阻塞。
- 跨域提示:直接请求谷歌官网会触发跨域限制,实际项目中建议通过后端代理转发请求,或确保目标接口配置了允许跨域的响应头。
内容的提问来源于stack exchange,提问作者user19575939
相关产品推荐
相关产品推荐

