Bootstrap模态框嵌套覆盖失效问题求助
Bootstrap 多层全屏模态框叠加异常问题
问题说明
基于《Multiple modals overlay》实现多层模态框功能,需求为:创建文件夹模态框,用户可在每个文件夹模态框内打开已有文件模态框或新建文件模态框,采用Bootstrap全屏模态框模式。
当前操作流程:
- 点击「Create new folder」按钮创建文件夹列表项
- 点击文件夹项打开对应的文件夹模态框
- 在文件夹模态框内点击按钮创建文件列表项
核心问题:点击文件列表项打开文件模态框时,原文件夹模态框会被自动关闭,无法实现多层模态框叠加显示。
问题代码
<!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> </head> <body> <button class="btn btn-primary" id="addnewfolder">Create new folder</button> <ul class="list-group folder"></ul> <script> $("#addnewfolder").click(function(event) { var code = (Math.random() + 1).toString(36).substring(7) $(".folder").append(`<li class="list-group-item"> <img src="https://img.icons8.com/officel/48/null/live-folder.png" class="float-start" /> <div class="ms-5" data-bs-toggle="modal" href="#modal-toggle-${code}">This is folder ${code}<br /> <div> <div class="modal fade" id="modal-toggle-${code}" aria-hidden="true" aria-labelledby="modal-toggleLabel" tabindex="-1"> <div class="modal-dialog modal-fullscreen"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" id="modal-toggleLabel">Inside Folder ${code}</h1> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <ul class="list-group file"></ul> <button data-bs-target="#modal-toggle2" data-bs-toggle="modal" class="btn btn-primary file-${code}">Add File Inside ${code}</button> </div> <div class="modal-footer"> <button class="btn btn-primary">Save</button> </div> </div> </div> </div> </div> </div> </li>`); //$(`#modal-toggle-${code}`).modal("show"); $(`.file-${code}`).click(function(event) { var dcode = Math.floor(Math.random() * 10); $(".file").append(`<li class="list-group-item"> <img src="https://img.icons8.com/cotton/64/null/happy-file.png" class="float-start" /> <div class="ms-5">This is file inside ${code}-${dcode}<br /> <small class="text-secondary">This is a ${code}-${dcode} item description</small> <div> <div class="modal fade" id="modal-toggle-${code}-${dcode}" aria-hidden="true" aria-labelledby="modal-toggleLabel" tabindex="-1"> <div class="modal-dialog modal-fullscreen"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" id="modal-toggleLabel">Inside Folder</h1> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> Hello World </div> <div class="modal-footer"> <button class="btn btn-primary">Save</button> </div> </div> </div> </div> </div> </div> </li>`); //$(`#modal-toggle-${code}-${dcode}`).modal("show"); }); }); $(document).on('show.bs.modal', '.modal', function() { const zIndex = 1040 + 10 * $('.modal:visible').length; $(this).css('z-index', zIndex); setTimeout(() => $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack')); }); </script> </body></html>
解决方案
问题根源
Bootstrap 默认行为是打开新模态框时自动关闭当前所有已打开的模态框,同时文件列表项未添加正确的模态框触发属性,导致点击时触发了默认的模态框关闭逻辑。
修复步骤
- 给文件列表项添加模态框触发属性:在文件列表项的触发区域(
.ms-5容器)添加data-bs-toggle="modal"和data-bs-target="#modal-toggle-${code}-${dcode}",确保点击时能正确触发对应的文件模态框。 - 阻止模态框触发时的事件冒泡:在打开文件模态框的事件中,阻止事件冒泡和默认行为,避免触发父级模态框的关闭逻辑。
- 修正代码中的语法错误:原头部的
<link>标签闭合错误,已修复。
修改后的完整代码
<!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> </head> <body> <button class="btn btn-primary" id="addnewfolder">Create new folder</button> <ul class="list-group folder"></ul> <script> $("#addnewfolder").click(function(event) { var code = (Math.random() + 1).toString(36).substring(7); $(".folder").append(`<li class="list-group-item"> <img src="https://img.icons8.com/officel/48/null/live-folder.png" class="float-start" /> <div class="ms-5" data-bs-toggle="modal" href="#modal-toggle-${code}">This is folder ${code}<br /> <div> <div class="modal fade" id="modal-toggle-${code}" aria-hidden="true" aria-labelledby="modal-toggleLabel" tabindex="-1"> <div class="modal-dialog modal-fullscreen"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" id="modal-toggleLabel">Inside Folder ${code}</h1> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <ul class="list-group file"></ul> <button class="btn btn-primary file-${code}">Add File Inside ${code}</button> </div> <div class="modal-footer"> <button class="btn btn-primary">Save</button> </div> </div> </div> </div> </div> </div> </li>`); $(`.file-${code}`).click(function(event) { var dcode = Math.floor(Math.random() * 10); // 给文件列表项添加模态框触发属性,并绑定点击事件阻止冒泡 $(".file").append(`<li class="list-group-item"> <img src="https://img.icons8.com/cotton/64/null/happy-file.png" class="float-start" /> <div class="ms-5 file-modal-trigger" data-bs-toggle="modal" data-bs-target="#modal-toggle-${code}-${dcode}"> This is file inside ${code}-${dcode}<br /> <small class="text-secondary">This is a ${code}-${dcode} item description</small> <div> <div class="modal fade" id="modal-toggle-${code}-${dcode}" aria-hidden="true" aria-labelledby="modal-toggleLabel" tabindex="-1"> <div class="modal-dialog modal-fullscreen"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" id="modal-toggleLabel">Inside File ${code}-${dcode}</h1> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> Hello World from File ${code}-${dcode} </div> <div class="modal-footer"> <button class="btn btn-primary">Save</button> </div> </div> </div> </div> </div> </div> </li>`); }); }); // 处理多层模态框的z-index和backdrop层级 $(document).on('show.bs.modal', '.modal', function(e) { // 阻止事件冒泡,避免关闭父模态框 e.stopPropagation(); const zIndex = 1040 + 10 * $('.modal:visible').length; $(this).css('z-index', zIndex); setTimeout(() => { $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack'); }, 0); }); // 关闭模态框时移除对应的backdrop $(document).on('hidden.bs.modal', '.modal', function() { $('.modal-stack').eq($('.modal:visible').length).remove(); }); </script> </body> </html>
修复效果
- 点击文件夹项打开文件夹模态框后,点击文件列表项可打开文件模态框,原文件夹模态框不会关闭,实现多层叠加显示
- 每层模态框的 backdrop 层级正确,不会出现遮挡问题
- 关闭上层模态框后,下层模态框可正常操作
内容的提问来源于stack exchange,提问作者user16731842
相关产品推荐
相关产品推荐

