我创建了以下解决方案,适用于 iOS 12!
虽然下面的嵌入式演示使用的是 Bootstrap 4,但同样的解决方案也适用于 Bootstrap 3,因为所有模式类或事件名称都不同。
第 1 步:在模态打开时使用固定定位将body 冻结到位
当一个 Bootstrap 模态打开时,一个名为 .modal-open 的类被添加到 body 中。将以下附加样式添加到此类:
body {
&.modal-open {
bottom: 0;
left: 0;
position: fixed;
right: 0;
top: 0;
}
}
现在,每当打开模式时,body 将固定在适当的位置,并调整为与视口本身相同的尺寸。这完全阻止了滚动,因为没有任何地方可以滚动!
但是:这也意味着打开模态框会导致页面跳转到顶部,因为body 不再超出视口的底部边缘(假设页面内容更高)。
第 2 步:在模态打开时模拟之前的滚动距离
Bootstrap 公开在打开或关闭模式时触发的事件。我们可以使用这些来解决“跳到顶部”的问题,方法是在打开模式时拉动body up 的顶部,这样看起来滚动位置没有改变:
$(function() {
var $window = $(window),
$body = $("body"),
$modal = $(".modal"),
scrollDistance = 0;
$modal.on("show.bs.modal", function() {
// Get the scroll distance at the time the modal was opened
scrollDistance = $window.scrollTop();
// Pull the top of the body up by that amount
$body.css("top", scrollDistance * -1);
});
});
但是,当模态框关闭时页面仍然会跳转到顶部,因为window的scrollTop值仍然是0。
第 3 步:关闭模式时重置所有内容
现在我们只需要挂钩在模式关闭时触发的事件,并将所有内容恢复原状:
- 移除
body上的固定定位和负上限值
- 将窗口的滚动位置设置回原来的位置
$modal.on("hidden.bs.modal", function() {
// Remove the negative top value on the body
$body.css("top", "");
// Set the window's scroll position back to what it was before the modal was opened
$window.scrollTop(scrollDistance);
});
无需手动移除body 上的固定定位,因为这是通过.modal-open 类设置的,Bootstrap 会在模态关闭时移除该类。
演示
将它们放在一起,现在您可以在模式打开时阻止 iOS 上的背景滚动,而不会丢失滚动位置!
在 iOS 设备上打开以下链接:https://daguy.github.io/ios-modal-fix/