Bootstrap嵌套模态框分层关闭问题及动态实现需求
Hey there! I've dealt with this exact nested modal quirk in Bootstrap 3 before—totally annoying when closing the child modal yanks the parent closed too. Let's build a dynamic solution that works regardless of what IDs your modals use, so you don't have to hardcode anything.
The Root Problem
Bootstrap 3's default data-dismiss="modal" behavior targets all modals with the .modal class, which means clicking any close button will close every open modal. We need to override this to only close the topmost active modal each time.
The Dynamic Solution
We'll listen for the modal close click event, prevent the default action, then target only the currently visible (and topmost) modal to close. This works even if your modal IDs change because we're using class selectors and DOM hierarchy instead of hardcoded IDs.
Here's the full working code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> <!-- Button trigger parent modal --> <button type="button" id="mymodal" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal"> Launch Parent Modal </button> <!-- Parent Modal --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="myModalLabel">Parent Modal</h4> </div> <div class="modal-body"> This is the parent modal content. <!-- Button trigger child modal --> <button type="button" id="mymodal-inner" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal-inner"> Launch Child Modal </button> <!-- Child Modal --> <div class="modal fade" id="myModal-inner" tabindex="-1" role="dialog" aria-labelledby="myModalLabel2"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title" id="myModalLabel2">Child Modal</h4> </div> <div class="modal-body"> This is the child modal content. Closing this won't close the parent now! </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close Child</button> <button type="button" class="btn btn-primary">Save Child Changes</button> </div> </div> </div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close Parent</button> <button type="button" class="btn btn-primary">Save Parent Changes</button> </div> </div> </div> </div> <script> // Override default modal close behavior for nested modals $(document).on('click', '[data-dismiss="modal"]', function(e) { e.preventDefault(); // Find the closest modal to the click (targets the topmost active modal) var $targetModal = $(this).closest('.modal'); // Only close this specific modal using Bootstrap's modal method $targetModal.modal('hide'); // Fix body scrollbar issue when closing the last modal if ($('.modal.in').length === 0) { $('body').removeClass('modal-open'); $('.modal-backdrop').remove(); } }); </script>
How It Works
- Dynamic Targeting: We use
$(this).closest('.modal')to find the modal containing the clicked close button—this works no matter what ID the modal has, or how deeply nested it is. - Prevent Default: We stop Bootstrap's default behavior that closes all modals at once.
- Clean Up Backdrops: When the last modal is closed, we manually remove the
modal-openclass from the body and leftover backdrop elements to fix scrollbar issues.
Now you can close the child modal first, then the parent modal independently—no more accidental double-closes!
内容的提问来源于stack exchange,提问作者Sanjeev Kumar

