twitter-bootstrap iOS 上的 BootStrap Modal 背景滚动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43563795/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 00:47:50  来源:igfitidea点击:

BootStrap Modal background scroll on iOS

ioscsstwitter-bootstrap

提问by juniortan

So there is this known issue with modal on iOS, when the modal is enabled swiping up/down will scroll the body instead of the modal.

因此,iOS 上的模态存在这个已知问题,当启用模态时,向上/向下滑动将滚动正文而不是模态。

Using bootstrap 3.3.7

使用引导程序 3.3.7

Tried to google it, most suggested adding

尝试谷歌它,最建议添加

body.modal-open {
  overflow: hidden !important;
}

but it doesn't work.

但它不起作用。

Some suggested,

有人建议,

body.modal-open {
  position: fixed;
}

But background will jump to the top of the page.

但是背景会跳到页面顶部。

So for now I am using,

所以现在我正在使用,

body.modal-open {
  overflow: hidden !important;
  position: fixed;
  width: 100%;
}
#exampleModal {
  background: black;
}

As a work-around so the jump can't be seen(but still noticeable)

作为一种解决方法,因此无法看到跳跃(但仍然很明显)

Is there other solutions to this?

有其他解决方案吗?

This is the site i am working on http://www.einproductions.com/

这是我正在使用的网站 http://www.einproductions.com/

回答by Klaas van der Weij

I've taken the solutions of @Aditya Prasanthi and @JIm, since one fixes the background-scrolling and the other fixes the skip-to-the-top after closing the modal, and turned them into one bare-minimum JS script:

我采用了@Aditya Prasanthi 和@JIm 的解决方案,因为一个修复了背景滚动,另一个修复了关闭模态后的跳转到顶部,并将它们变成了一个最低限度的 JS 脚本:

let previousScrollY = 0;

$(document).on('show.bs.modal', () => {
    previousScrollY = window.scrollY;
    $('html').addClass('modal-open').css({
        marginTop: -previousScrollY,
        overflow: 'hidden',
        left: 0,
        right: 0,
        top: 0,
        bottom: 0,
        position: 'fixed',
    });
}).on('hidden.bs.modal', () => {
    $('html').removeClass('modal-open').css({
        marginTop: 0,
        overflow: 'visible',
        left: 'auto',
        right: 'auto',
        top: 'auto',
        bottom: 'auto',
        position: 'static',
    });
    window.scrollTo(0, previousScrollY);
});

It's, of course, possible and even adviced to use a class to set and unset the CSS for the body, however, I choose this solution to resolve a problem just in one place (and not require external CSS as well).

当然,可以甚至建议使用类来设置和取消设置正文的 CSS,但是,我选择此解决方案仅在一个地方解决问题(并且不需要外部 CSS)。

回答by Aditya Prasanthi

refer to Does overflow:hidden applied to <body> work on iPhone Safari?

请参阅溢出:隐藏应用于 <body> 是否在 iPhone Safari 上工作?

Added .freezePage to html and body when modal is showing

显示模态时将 .freezePage 添加到 html 和 body

$('.modal').on('shown.bs.modal', function (e) {
  $('html').addClass('freezePage'); 
  $('body').addClass('freezePage');
});
$('.modal').on('hidden.bs.modal', function (e) {
  $('html').removeClass('freezePage');
  $('body').removeClass('freezePage');
});

the CSS

CSS

.freezePage{
  overflow: hidden;
  height: 100%;
  position: relative;
}

回答by JIm

My solution:

我的解决方案:

scrollPos = window.scrollY  - get current scroll position.

body { position: fixed;
   margin-top: -**scrollPos** px);

}

}

Then modal is closed:

然后模态关闭:

body {position: "";
  margin-top: "";

}

}

and return scroll position to point before opened modal window:

并将滚动位置返回到打开模态窗口之前的点:

window.scrollTo(0, scrollPos);

回答by kofifus

None of the above answers worked for me, the modal kept disappearing and I ended up with a brute force approach which is ugly and inefficient but works !

以上答案都不适合我,模态一直消失,我最终采用了一种丑陋且低效但有效的蛮力方法!

$('body').on('touchstart touchmove touchend', e => {
    let scrollDisabled=$('.scroll-disable');
    if (scrollDisabled.length > 0 &&  scrollDisabled.has($(e.target)).length===0) {
        e.preventDefault(); 
        e.stopPropagation();
    }
});
setInterval(() => $('.modal:visible').css('top', '20px'), 100);

$(document).on({
    'show.bs.modal': e => $(e.target).addClass('scroll-disable'),
    'hidden.bs.modal': e => $(e.target).removeClass('scroll-disable')
}, '.modal');

回答by Kuldeep Bhimte

Import this file and use the enableBodyScrolland disableBodyScrollfunctions to lock and unlock the body scroll.

导入此文件并使用enableBodyScrolldisableBodyScroll函数锁定和解锁主体卷轴。

using csstopproperty will exactly navigate back to the previous position. It eliminate the drawback of dealing with the floating point margin.

usingcsstop属性将准确导航回之前的位置。它消除了处理浮点边距的缺点。

const toggleBodyScroll = (position, initialMargin) => {
  document.body.style.position = position;
  document.body.style.top = initialMargin;
};

const getScrolledPosition = () => {
  return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
};

const scrollToPrevPosition = (scrolledPosition) => {
  window.scrollTo(0, scrolledPosition);
};

const getWindowTop = () => {
  return window.getComputedStyle(document.body).getPropertyValue('top');
};

export const disableBodyScroll = () => {
  toggleBodyScroll('fixed', `-${getScrolledPosition()}px`);
};

export const enableBodyScroll = () => {
  const scrollPosition = 0 - parseInt(getWindowTop());
  toggleBodyScroll('static', 0);
  scrollToPrevPosition(scrollPosition);
};

回答by trop yes

This will prevent page scrolling while Modal is opened on iOS mobile

这将防止在 iOS 移动设备上打开 Modal 时页面滚动

if ($(window).width() < 960) {
        let previousScrollY = 0;
        $(document).on('show.bs.modal', () => {
            previousScrollY = window.scrollY;
            $('html').addClass('modal-open').css({
                marginTop: -previousScrollY,
                overflow: 'hidden',
                left: 0,
                right: 0,
                top: 0,
                bottom: 0,
                position: 'fixed',
            });

        }).on('hidden.bs.modal', () => {
            $('html').removeClass('modal-open').css({
                marginTop: 0,
                overflow: 'visible',
                left: 'auto',
                right: 'auto',
                top: 'auto',
                bottom: 'auto',
                position: 'static',
            });
            window.scrollTo(0, previousScrollY);
        });
    }