Bootstrap 模态框组件 #
模态框(Modal)是一种覆盖在页面上的弹窗组件,用于显示重要信息、收集用户输入或确认操作。Bootstrap 的模态框组件功能强大,支持多种尺寸、动画效果和自定义内容。
基础模态框 #
基本结构 #
html
<!-- 触发按钮 -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
打开模态框
</button>
<!-- 模态框 -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">模态框标题</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="关闭"></button>
</div>
<div class="modal-body">
<p>这是模态框的内容区域。</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary">保存</button>
</div>
</div>
</div>
</div>
结构解析 #
| 元素 | 类名 | 作用 |
|---|---|---|
| 模态框容器 | .modal |
模态框主容器 |
| 淡入淡出 | .fade |
动画效果 |
| 对话框 | .modal-dialog |
对话框容器 |
| 内容区 | .modal-content |
内容包装器 |
| 头部 | .modal-header |
标题和关闭按钮 |
| 标题 | .modal-title |
模态框标题 |
| 主体 | .modal-body |
主要内容区域 |
| 底部 | .modal-footer |
操作按钮区域 |
静态背景 #
默认情况下,点击模态框外部会关闭模态框。使用 data-bs-backdrop="static" 可以禁用此行为:
html
<div class="modal fade" data-bs-backdrop="static">
...
</div>
禁用键盘关闭 #
使用 data-bs-keyboard="false" 禁用 ESC 键关闭:
html
<div class="modal fade" data-bs-keyboard="false">
...
</div>
模态框尺寸 #
小尺寸 #
html
<div class="modal-dialog modal-sm">
...
</div>
默认尺寸 #
html
<div class="modal-dialog">
...
</div>
大尺寸 #
html
<div class="modal-dialog modal-lg">
...
</div>
超大尺寸 #
html
<div class="modal-dialog modal-xl">
...
</div>
全屏模态框 #
html
<!-- 始终全屏 -->
<div class="modal-dialog modal-fullscreen">
...
</div>
<!-- 响应式全屏 -->
<div class="modal-dialog modal-fullscreen-sm-down">小屏全屏</div>
<div class="modal-dialog modal-fullscreen-md-down">中屏全屏</div>
<div class="modal-dialog modal-fullscreen-lg-down">大屏全屏</div>
<div class="modal-dialog modal-fullscreen-xl-down">超大屏全屏</div>
<div class="modal-dialog modal-fullscreen-xxl-down">超大屏全屏</div>
垂直居中 #
使用 .modal-dialog-centered 使模态框垂直居中:
html
<div class="modal-dialog modal-dialog-centered">
...
</div>
滚动长内容 #
模态框内滚动 #
html
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">长内容模态框</h5>
</div>
<div class="modal-body">
<p>很长的内容...</p>
<p>很长的内容...</p>
</div>
</div>
</div>
实战案例 #
确认对话框 #
html
<!-- 触发按钮 -->
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#confirmModal">
删除
</button>
<!-- 确认模态框 -->
<div class="modal fade" id="confirmModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">确认删除</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>确定要删除此项目吗?此操作无法撤销。</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-danger">确认删除</button>
</div>
</div>
</div>
</div>
表单模态框 #
html
<!-- 触发按钮 -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#formModal">
添加用户
</button>
<!-- 表单模态框 -->
<div class="modal fade" id="formModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">添加用户</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label class="form-label">姓名</label>
<input type="text" class="form-control" placeholder="请输入姓名">
</div>
<div class="mb-3">
<label class="form-label">邮箱</label>
<input type="email" class="form-control" placeholder="请输入邮箱">
</div>
<div class="mb-3">
<label class="form-label">角色</label>
<select class="form-select">
<option>管理员</option>
<option>编辑</option>
<option>用户</option>
</select>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary">保存</button>
</div>
</div>
</div>
</div>
图片预览模态框 #
html
<!-- 触发图片 -->
<img src="thumbnail.jpg" class="img-thumbnail" style="cursor: pointer;"
data-bs-toggle="modal" data-bs-target="#imageModal">
<!-- 图片模态框 -->
<div class="modal fade" id="imageModal" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content bg-transparent border-0">
<div class="modal-body p-0 text-center">
<img src="full-image.jpg" class="img-fluid rounded">
</div>
</div>
</div>
</div>
登录模态框 #
html
<!-- 触发按钮 -->
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#loginModal">
登录
</button>
<!-- 登录模态框 -->
<div class="modal fade" id="loginModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header border-0">
<h5 class="modal-title">登录</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label class="form-label">邮箱</label>
<input type="email" class="form-control" placeholder="请输入邮箱">
</div>
<div class="mb-3">
<label class="form-label">密码</label>
<input type="password" class="form-control" placeholder="请输入密码">
</div>
<div class="d-flex justify-content-between mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="remember">
<label class="form-check-label" for="remember">记住我</label>
</div>
<a href="#" class="text-decoration-none">忘记密码?</a>
</div>
<div class="d-grid">
<button class="btn btn-primary" type="submit">登录</button>
</div>
</form>
</div>
<div class="modal-footer border-0 justify-content-center">
<span class="text-muted">还没有账号?</span>
<a href="#" class="text-decoration-none">立即注册</a>
</div>
</div>
</div>
</div>
详情模态框 #
html
<!-- 触发按钮 -->
<button type="button" class="btn btn-link" data-bs-toggle="modal" data-bs-target="#detailModal">
查看详情
</button>
<!-- 详情模态框 -->
<div class="modal fade" id="detailModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">产品详情</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-4">
<img src="product.jpg" class="img-fluid rounded">
</div>
<div class="col-md-8">
<h4>产品名称</h4>
<p class="text-danger fw-bold">¥99.00</p>
<p>产品详细描述信息...</p>
<table class="table table-sm">
<tbody>
<tr><th>品牌</th><td>品牌名</td></tr>
<tr><th>型号</th><td>型号</td></tr>
<tr><th>规格</th><td>规格</td></tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary">加入购物车</button>
</div>
</div>
</div>
</div>
JavaScript API #
通过 JavaScript 打开 #
javascript
var myModal = new bootstrap.Modal(document.getElementById('myModal'));
myModal.show();
配置选项 #
javascript
var myModal = new bootstrap.Modal(document.getElementById('myModal'), {
backdrop: true, // 点击背景是否关闭
keyboard: true, // ESC 键是否关闭
focus: true // 打开时是否聚焦
});
方法 #
javascript
// 显示
myModal.show();
// 隐藏
myModal.hide();
// 切换
myModal.toggle();
// 更新
myModal.handleUpdate();
// 销毁
myModal.dispose();
事件 #
javascript
var myModal = document.getElementById('myModal');
// 显示前触发
myModal.addEventListener('show.bs.modal', function() {
console.log('模态框即将显示');
});
// 显示后触发
myModal.addEventListener('shown.bs.modal', function() {
console.log('模态框已显示');
});
// 隐藏前触发
myModal.addEventListener('hide.bs.modal', function() {
console.log('模态框即将隐藏');
});
// 隐藏后触发
myModal.addEventListener('hidden.bs.modal', function() {
console.log('模态框已隐藏');
});
// 隐藏被阻止时触发
myModal.addEventListener('hidePrevented.bs.modal', function() {
console.log('隐藏被阻止');
});
| 事件类型 | 说明 |
|---|---|
show.bs.modal |
调用 show 方法时触发 |
shown.bs.modal |
模态框完全显示后触发 |
hide.bs.modal |
调用 hide 方法时触发 |
hidden.bs.modal |
模态框完全隐藏后触发 |
hidePrevented.bs.modal |
点击背景或 ESC 键但被阻止时触发 |
动态内容 #
通过 data 属性传递数据 #
html
<button type="button" class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#dynamicModal"
data-id="123"
data-name="产品名称">
查看详情
</button>
<div class="modal fade" id="dynamicModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<p id="modalContent"></p>
</div>
</div>
</div>
</div>
<script>
document.getElementById('dynamicModal').addEventListener('show.bs.modal', function(event) {
var button = event.relatedTarget;
var id = button.getAttribute('data-id');
var name = button.getAttribute('data-name');
var modalBody = this.querySelector('#modalContent');
modalBody.textContent = 'ID: ' + id + ', 名称: ' + name;
});
</script>
嵌套模态框 #
Bootstrap 不支持嵌套模态框,建议使用其他方式:
html
<!-- 不推荐:嵌套模态框 -->
<div class="modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<button data-bs-toggle="modal" data-bs-target="#modal2">
打开另一个模态框
</button>
</div>
</div>
</div>
</div>
推荐做法:先关闭当前模态框,再打开新模态框:
javascript
// 先隐藏当前模态框
$('#modal1').modal('hide');
// 监听隐藏完成事件
$('#modal1').on('hidden.bs.modal', function() {
// 打开新模态框
$('#modal2').modal('show');
});
最佳实践 #
1. 模态框位置 #
将模态框放在页面底部,避免嵌套在其他元素中:
html
<body>
<!-- 页面内容 -->
<!-- 模态框放在最后 -->
<div class="modal fade" id="myModal">...</div>
</body>
2. 可访问性 #
html
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="myModalLabel">标题</h5>
</div>
</div>
</div>
</div>
3. 关闭按钮 #
html
<!-- 推荐:使用 btn-close -->
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="关闭"></button>
<!-- 或使用文字按钮 -->
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
4. 防止滚动条跳动 #
css
/* 模态框打开时防止页面滚动条跳动 */
body.modal-open {
overflow: hidden;
padding-right: 0 !important;
}
常见问题 #
1. 模态框不显示? #
检查是否引入了 Bootstrap JavaScript:
html
<script src="bootstrap.bundle.min.js"></script>
2. 点击按钮无反应? #
检查 data-bs-toggle 和 data-bs-target 属性:
html
<button data-bs-toggle="modal" data-bs-target="#myModal">打开</button>
3. 模态框背景变暗? #
确保模态框放在 .modal-backdrop 外面,通常放在 body 最后。
4. 模态框内容动态更新后滚动问题? #
调用 handleUpdate() 方法:
javascript
myModal.handleUpdate();
下一步 #
现在你已经掌握了模态框组件,接下来学习 工具类,了解 Bootstrap 提供的各种实用工具类!
最后更新:2026-03-28