仅在模态为开放式IOS时如何禁用正文滚动

时间:2019-02-20 12:56:17

标签: html css twitter-bootstrap-3 bootstrap-modal

仅iOS / iPhone X / iPhone 7等

即使jquery模态库也不起作用! https://jquerymodal.com/-在iPhone上打开模态,就可以滚动主体。

我发现很难找到一种解决方案,该解决方案可以在每次打开模态时停止主体滚动而不使页面跳到顶部(这与页面滚动一样糟糕)

这似乎是很多人都遇到的一个大问题。如您所见: -How to disable body scrolling when modal is open IOS only -How to prevent body scrolling on iOS 12 when modal opened? -Stopping Body scroll on modal open Bootstrap 4

我没有运气就上网了,有人可以解决吗?!

3 个答案:

答案 0 :(得分:3)

我创建了以下解决方案,该解决方案可在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);
    });
});

但是,由于scrollTop的{​​{1}}值仍为window,因此关闭模式时页面仍将跳至顶部。

第3步:关闭模式后,重置所有内容

现在,我们只需要挂接到模式关闭时触发的事件,然后将一切恢复原状即可:

  • 删除0上的固定位置和负最高值
  • 将窗口的滚动位置设置回原来的位置
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类设置的,Bootstrap在模式关闭时会删除该类。


演示

将它们放在一起,现在您可以防止在打开模式时在iOS上进行背景滚动而不会丢失滚动位置!

在iOS设备上打开以下链接:https://daguy.github.io/ios-modal-fix/

答案 1 :(得分:0)

export default class BackgroundScroll {
  private scrollPosition = 0;
  disable = (isDisable) => {
    if (isDisable) {
      this.scrollPosition = window.pageYOffset;
      document.body.classList.add('block-body-scroll');
      document.body.style.top = `-${this.scrollPosition}px`;
      if (this.checkIos()) {
        document.body.classList.add('ios');
      }
    } else {
      document.body.classList.remove('block-body-scroll');
      window.scrollTo(0, this.scrollPosition);
    }
  };

  private checkIos(): boolean {
    return (
      ['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(
        navigator.platform
      ) ||
      (navigator.userAgent.includes('Mac') && 'ontouchend' in document)
    );
  }
}
body.block-body-scroll {
  overflow: hidden;
  width: 100%;
  &.ios {
    position: fixed;
  }
}

我们只为 ios 处理 position: fixed。因为 position: fixed 会像 Firefox 一样影响其他浏览器。这是我在打字稿上处理的代码,但纯 JS 或其他任何东西与我的基本相同。

答案 2 :(得分:-1)

嗯,我看到关于SO的话题已经很少了。 尝试这个吧?

@supports (-webkit-overflow-scrolling: touch) {
  /* CSS specific to iOS devices */ 
}

@supports not (-webkit-overflow-scrolling: touch) {
  /* CSS for other than iOS devices */ 
}

CSS media query target only iOS devices