Bootstrap模态框无法叠加显示,点击保存报backdrop未定义错误
问题分析与修复方案
问题根源
- Save按钮无效属性触发错误:按钮上的
data-bs-target="#exampleModalToggle2"和data-bs-toggle="modal"指向不存在的模态框,Bootstrap尝试切换时会抛出Cannot read properties of undefined (reading 'backdrop')错误,同时默认关闭当前打开的原模态框。 - Toast模态框无渲染容器:
showToast函数试图将模态框内容插入$("#modal"),但页面中没有这个元素,导致模态框HTML无法渲染,进一步引发找不到目标元素的问题。 - 模态框层级不足:即使Toast模态框能显示,默认层级低于原模态框,无法实现叠加效果。
修复步骤
- 清理Save按钮无效属性:移除
data-bs-target和data-bs-toggle,仅保留触发showToast的onclick事件,避免Bootstrap自动触发模态框切换行为。 - 添加Toast渲染容器:在页面中新增
<div id="modal"></div>,让showToast有固定的DOM位置渲染模态框。 - 提升Toast模态框层级:通过自定义CSS设置Toast模态框内容的
z-index高于原模态框,确保叠加显示。 - 优化模态框初始化逻辑:在
showToast中增加元素存在性判断,避免因DOM未渲染完成引发错误。
修改后的完整代码
<!doctype html> <html lang="en"> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script> <style> /* 提升Toast模态框层级,确保叠加在原模态框上方 */ #messagemodal .modal-content { z-index: 1060; } </style> </head> <body> <button id="clickme">Click me here</button> <ul class="list-group task-point"></ul> <!-- 添加Toast模态框的渲染容器 --> <div id="modal"></div> <script> function showToast(m, title="Error") { $("#modal").html(` <div class="modal fade" id="messagemodal" tabindex="-1" role="dialog" aria-labelledby="messagemodalLabel" aria-hidden="true"> <div class="modal-dialog modal-sm modal-dialog-centered" role="document"> <div class="modal-content"> <div class="p-2 modal-header"> <h5 class="ms-2 modal-title" id="messagemodalLabel">${title}</h5> <button type="button" class="me-1 btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="text-start modal-body"> ${m}<br/><br/> </div> </div> </div> </div> `); // 确保元素存在后再初始化模态框 const modalEl = document.getElementById('messagemodal'); if (modalEl) { const modal = new bootstrap.Modal(modalEl, { keyboard: false }); modal.show(); } } $("#clickme").click(function (event) { const code = $(".dropdown-menu").length + 1; $(".task-point").append(` <li class="list-group-item"> <img src="https://img.icons8.com/color/48/000000/networking-manager.png" class="float-start" /> <div class="btn-group float-end"> <button type="button" class="btn dropdown-toggle" data-bs-toggle="dropdown" data-bs-display="static" aria-expanded="false"> Action </button> <ul class="dropdown-menu dropdown-menu-lg-end"> <li><a data-bs-toggle="modal" href="#exampleModalToggle-${code}" role="button" class="dropdown-item">Edit ${code}</a></li> <li><a class="dropdown-item" href="#">Delete ${code}</a></li> <li><a class="dropdown-item" href="#">Run ${code}</a></li> </ul> </div> <div class="ms-5"> This is ${code} item<br/> <small class="text-secondary">This is a ${code} item description</small> </div> <div class="modal fade" id="exampleModalToggle-${code}" aria-hidden="true" aria-labelledby="exampleModalToggleLabel-${code}" tabindex="-1"> <div class="modal-dialog modal-fullscreen"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" id="exampleModalToggleLabel-${code}">Create a file</h1> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> What is Lorem Ipsum? </div> <div class="modal-footer"> <!-- 移除无效的data-bs属性,只保留onclick --> <button class="btn btn-primary" onclick="showToast('Thanks for saving', 'Success');">Save</button> </div> </div> </div> </div> </li> `); $(`#exampleModalToggle-${code}`).modal("show"); }) </script> </body> </html>
额外优化建议
- 可将Toast模态框的HTML结构提前写在页面中(默认隐藏),调用
showToast时仅修改标题和内容再显示,避免重复创建DOM元素,提升性能。 - 给Toast模态框添加自动关闭逻辑,比如
setTimeout(() => modal.hide(), 3000),优化用户体验。
内容的提问来源于stack exchange,提问作者Code Guy
相关产品推荐
相关产品推荐

