css 如何禁用身体滚动时,模态是打开IOS只

uklbhaso  于 2022-12-15  发布在  iOS
关注(0)|答案(4)|浏览(148)

仅适用于iOS/ iPhone X / iPhone 7等
甚至jquery模态库也不起作用!https://jquerymodal.com/-在iPhone上打开模态库,你就可以滚动正文了。
我发现很难找到一个解决方案,停止身体滚动,而不使页面跳到顶部,每次模态打开(这是一样糟糕的经验,因为页面滚动)
看起来这是一个大问题,很多人都经历过这个问题。正如你在这里看到的:

我在互联网上搜寻没有运气,有人有办法吗?!

zujrkrfu

zujrkrfu1#

我已经创建了以下解决方案,它适用于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;
    }
}

现在只要打开一个modal,body就会被固定在原地,并且大小和viewport本身一样,这就完全阻止了滚动,因为没有地方可以滚动!
但是:这也意味着打开一个modal会导致页面跳到顶部,因为body不再超出视口的底部边缘(假设页面内容更高)。

第2步:在模态打开时模拟上一个滚动距离

Bootstrap暴露了当模态打开或关闭时触发的事件,我们可以使用这些事件来解决“跳转到顶部”的问题,方法是在模态打开时将body的顶部拉上,这样看起来滚动位置没有改变:

$(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);
    });
});

但是,当模态关闭时,页面仍然会跳转到顶部,因为windowscrollTop值仍然是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/

643ylb08

643ylb082#

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一样影响其他浏览器。这是我在typescript上处理的代码,但纯JS或其他任何东西基本上和我的一样。

3bygqnnd

3bygqnnd3#

经过大量的试错,我得出了:

/* Default (phone) */
body.modal-open {
    left: 0;
    position: fixed;
    right: 0;
    /* Prevent scrolling of body */
    overflow-y: hidden !important;
}

/* Small and above e.g. not a phone */
@media (min-width: 576px) {
    body.modal-open {
        /* Keep scrollbar */
        overflow-y: scroll !important;
    }
}

在默认模式下(手机),我只是删除了垂直滚动条。因为它在手机上,它坐在顶部,没有宽度。没有溢出y,手机不能滚动。
但是在桌面上,我喜欢永久水平滚动,所以我在模态期间强制它打开,以防止屏幕以17 px的宽度移位。
如果在桌面上(全宽滚动条),如果用户将浏览器缩小到576 px以下,你会得到一个转变,但我可以接受。
另外--我允许在模态中滚动,这样模态就不会在移动的屏幕的底部滚动。

euoag5mw

euoag5mw4#

嗯,我看到已经有一些主题了,试试这个吧?

@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

相关问题