解决多层Bootstrap模态框关闭后再次打开偏移量翻倍的问题
解决多层Bootstrap模态框关闭后再次打开偏移量翻倍的问题
我明白你遇到的问题了——关闭上层模态框后再重新打开,偏移量会莫名从20px变成40px,完全不符合预期。咱们先拆解问题原因,再给出修复后的完整代码。
问题根源分析
你当前的代码有几个关键问题:
- 不必要的
$(document).ready嵌套:openModal函数是点击触发的,此时文档早已加载完成,这个嵌套会导致代码执行时机混乱,甚至后续调用时逻辑不生效。 - 偏移量设置时机不对:在模态框还未完全显示时就设置偏移,可能被Bootstrap的默认定位逻辑覆盖。
- 未重置模态框的初始位置:关闭模态框后,之前设置的偏移量会保留在DOM元素上,再次打开时叠加导致偏移翻倍。
修复后的代码实现
我们调整逻辑,确保每次打开模态框时:
- 先获取当前已打开的模态框数量,计算正确的偏移量
- 等待模态框完全显示后再设置偏移(利用Bootstrap的
shown.bs.modal事件) - 移除多余的
ready嵌套,保证每次调用函数都执行完整逻辑
<!DOCTYPE html> <html> <head> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <script src="https://code.jquery.com/jquery-3.1.0.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <style> body { background: transparent; /* 你可以改成白色 */ color: #fcbe24; padding: 0 24px; margin: 0; height: 100vh; display: flex; justify-content: center; align-items: center; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } </style> </head> <body> <button onclick="openModal( $('#modal-1') )">Show modal 1</button> <div class="modal" tabindex="-1" role="dialog" id="modal-1"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Modal title</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <h2>Modal 1</h2> <p> <button onclick="openModal( $('#modal-2') )">Show modal 2</button> </p> </div> <div class="modal-footer"> <button type="button" class="btn btn-primary">Save changes</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> </div> </div> </div> </div> <div class="modal" tabindex="-1" role="dialog" id="modal-2"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Modal title</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <h2>Modal 2</h2> </div> <div class="modal-footer"> <button type="button" class="btn btn-primary">Save changes</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> </div> </div> </div> </div> <script> function openModal(ele) { // 获取当前已打开的模态框数量(排除即将打开的这个) const openedModals = $(".modal.show").not(ele); const offsetLevel = openedModals.length; const offsetValue = 20 * offsetLevel; // 先显示模态框 ele.modal("show"); // 监听模态框完全显示的事件,再设置偏移(用one避免重复绑定) ele.one("shown.bs.modal", function() { // 先重置模态框内联样式,清除之前的偏移残留 ele.css({ top: "", left: "" }); // 设置新的偏移量 ele.offset({ left: offsetValue, top: offsetValue }); }); } </script> </body> </html>
关键逻辑说明
$(".modal.show").not(ele):准确获取已经打开的模态框,排除当前要打开的这个,确保偏移层级计算正确。ele.one("shown.bs.modal", ...):用one而不是on,避免多次绑定事件导致重复执行逻辑。ele.css({ top: "", left: "" }):重置模态框的内联样式,清除之前的偏移残留,从Bootstrap的默认位置开始设置新偏移。
这样调整后,不管你重复打开、关闭多少次模态框,偏移量都会保持正确的层级,再也不会出现翻倍的问题啦。
内容来源于stack exchange
相关产品推荐
相关产品推荐

