Bootstrap 5.0.0结合Webpacker实现动态模态框的问题与解决方案
Bootstrap 5.x 动态加载Modal报错的规避方案
问题背景
自Bootstrap 5.0.0版本发布以来,动态加载的Modal(模态框)及相关组件经常出现初始化异常,问题根源是Bootstrap 5.x的组件初始化逻辑依赖DOM树完全加载,若JS在head中提前加载执行,会找不到所需的DOM元素。
该问题确实存在,在Bootstrap 5.x正式版中,无论你通过JS动态初始化模态框,还是通过Data属性初始化模态框,都会触发该问题。
目前已知的临时解决方案是将bootstrap.bundle.js放在HTML的body标签内加载,而非放在head标签中,但这并非该问题的理想最终解法。
典型报错信息
// 使用JS触发模态框显示时出现该错误 var modal = new bootstrap.Modal(document.getElementById('my-modal')); modal.show(); // Uncaught TypeError: BACKDROP: Option "rootElement" provided type "null" but expected type "element". // typeCheckConfig bootstrap.bundle.js:190 // typeCheckConfig bootstrap.bundle.js:184 // _getConfig bootstrap.bundle.js:4603 // Backdrop bootstrap.bundle.js:4539 // _initializeBackDrop bootstrap.bundle.js:4864 // Modal bootstrap.bundle.js:4721 // <anonymous> debugger eval code:2
其他可行规避方案(无需将JS放到body末尾)
- 监听DOM加载完成事件后再执行初始化逻辑,代码示例:
document.addEventListener('DOMContentLoaded', function() { const modalEl = document.getElementById('my-modal'); const modal = new bootstrap.Modal(modalEl); modal.show(); })
- 初始化Modal时显式传入
rootElement配置,手动指定根元素规避默认取值为空的问题,代码示例:
const modalEl = document.getElementById('my-modal'); const modal = new bootstrap.Modal(modalEl, { rootElement: document.body }); modal.show();
- 给head中的JS标签添加
defer属性,保证JS按顺序加载且在DOM解析完成后再执行,代码示例:
<head> <!-- 先加载Bootstrap JS,加defer属性 --> <script src="path/to/bootstrap.bundle.js" defer></script> <!-- 再加载业务JS,加defer属性 --> <script src="path/to/your-business.js" defer></script> </head>
已验证的最简解决方案
最简便的规避方案是将你的JS代码加载位置移到<body>标签末尾,Rails环境示例如下:
# app/views/layout/application.html.erb <body> <%= yield %> <%# 此处的`javascript_pack_tag`原本放在`<head>`标签内 %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> </body>
内容的提问来源于stack exchange,提问作者Sumak
相关产品推荐
相关产品推荐

