如何避免打开多个Bootstrap模态框时模态框滚动位置意外偏移
如何避免打开多个Bootstrap模态框时模态框滚动位置意外偏移
我太懂你这种困扰了——当第一个模态框已经滚动到下方,点按钮打开第二个模态框时,第一个模态框的滚动条居然直接跳回顶部,而且还有些时灵时不灵的触发场景,用起来特别别扭。别担心,咱们来一步步解决这个问题。
问题原因
其实这是Bootstrap处理多模态框叠加时的一个小“副作用”:当显示新的模态框时,Bootstrap会调整页面的滚动样式(比如给body加modal-open类、隐藏页面滚动条),这个过程中会间接导致第一个模态框的滚动容器(也就是.modal-body)的滚动位置被意外重置。
解决方案:手动保存并恢复滚动位置
我们只需要在打开第二个模态框前,先把第一个模态框的滚动位置存下来,等第二个模态框完全显示后,再把这个位置恢复回去就行。下面是修改后的代码:
修改后的JavaScript代码
$(document).ready(() => { // 用于存储第一个模态框的滚动位置 let modal1ScrollPosition = 0; // 缓存DOM元素,减少重复查询 const $modal1Body = $('#exampleModalToggle .modal-body'); const $modal2 = $('#exampleModalToggle2'); // 打开第一个模态框的逻辑 $('#openExampleModalToggle').on('click', () => { $('#exampleModalToggle').modal('show'); }); // 打开第二个模态框的逻辑 $('#openExampleModalToggle2').on('click', () => { // 先保存第一个模态框当前的滚动位置 modal1ScrollPosition = $modal1Body.scrollTop(); // 再打开第二个模态框 $modal2.modal('show'); }); // 当第二个模态框完全显示后,恢复第一个模态框的滚动位置 $modal2.on('shown.bs.modal', () => { $modal1Body.scrollTop(modal1ScrollPosition); }); // 当第一个模态框关闭时,重置滚动位置变量 $('#exampleModalToggle').on('hidden.bs.modal', () => { modal1ScrollPosition = 0; }); });
对应的HTML代码(可直接使用你原来的代码)
<script src="https://code.jquery.com/jquery-1.12.4.js" integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU=" crossorigin="anonymous"></script> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script> <div class="modal fade" id="exampleModalToggle" aria-hidden="true" aria-labelledby="exampleModalToggleLabel" tabindex="-1"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" id="exampleModalToggleLabel">Modal 1</h1> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> Show a second modal and hide this one with the button below. <br><br><br><br><br><br><br><br><br><br><br><br><br><br> Show a second modal and hide this one with the button below. </div> <div class="modal-footer"> <button class="btn btn-primary" id="openExampleModalToggle2">Open second modal</button> </div> </div> </div> </div> <div class="modal fade" id="exampleModalToggle2" aria-hidden="true" aria-labelledby="exampleModalToggleLabel2" tabindex="-1"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" id="exampleModalToggleLabel2">Modal 2</h1> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> Hide this modal and show the first with the button below. </div> <div class="modal-footer"> </div> </div> </div> </div> <button class="btn btn-primary" id="openExampleModalToggle">Open first modal</button>
代码说明
- 保存滚动位置:在点击打开第二个模态框的瞬间,先把第一个模态框
.modal-body的当前滚动位置存到变量里。 - 恢复滚动位置:等第二个模态框完全显示出来(用
shown.bs.modal事件确保渲染完成),再把第一个模态框的滚动位置设置回之前保存的值。 - 重置变量:当第一个模态框关闭时,把滚动位置变量重置,避免下次打开模态框时使用旧的位置数据。
这样修改后,不管你是第一次打开第二个模态框,还是关闭后再打开,或者关闭第一个模态框重新操作,第一个模态框的滚动位置都能稳稳保留在你之前滚动到的地方啦。
备注:内容来源于stack exchange,提问作者백인우
相关产品推荐
相关产品推荐

