Bootstrap 3 modal在移动平台上打开时如何防止背景滚动?在桌面浏览器上,背景被阻止滚动并正常工作。
在移动浏览器(Safari ios、Chrome ios 等)上,当打开一个模态并使用手指滚动它时,背景也会像模态一样滚动。我该如何防止呢?
Bootstrap 3 modal在移动平台上打开时如何防止背景滚动?在桌面浏览器上,背景被阻止滚动并正常工作。
在移动浏览器(Safari ios、Chrome ios 等)上,当打开一个模态并使用手指滚动它时,背景也会像模态一样滚动。我该如何防止呢?
见这里:https ://github.com/twbs/bootstrap/issues/7501
所以试试:
$('body').css('overflow','hidden');
$('body').css('position','fixed');
V3.0.0。应该已经解决了这个问题。你用的是最新版本吗?如果是这样,请在https://github.com/twbs/bootstrap/上发布问题
Try this,
body.modal-open {
overflow: hidden;
position:fixed;
width: 100%;
}
我尝试了接受的答案,该答案阻止了正文滚动,但出现了滚动到顶部的问题。这应该可以解决这两个问题。
附带说明一下,它似乎溢出:隐藏在 iOS Safari 的主体上不起作用,因为 iOS Chrome 工作正常。
var scrollPos = 0;
$('.modal')
.on('show.bs.modal', function (){
scrollPos = $('body').scrollTop();
$('body').css({
overflow: 'hidden',
position: 'fixed',
top : -scrollPos
});
})
.on('hide.bs.modal', function (){
$('body').css({
overflow: '',
position: '',
top: ''
}).scrollTop(scrollPos);
});
$('.modal')
.on('shown', function(){
console.log('show');
$('body').css({overflow: 'hidden'});
})
.on('hidden', function(){
$('body').css({overflow: ''});
});
use this one
不需要脚本。
BS 3 在 body 上设置了一个 .modal-open 类,您可以使用它来设置位置和溢出值(使用 LESS 制作)。
body {
font-family:'Open Sans';
margin:0;
&.modal-open {
position:fixed;
overflow:hidden;
.modal {
overflow: scroll;
@media only screen and (min-resolution:150dpi) and (max-width: @screen-sm),
only screen and (-webkit-min-device-pixel-ratio:1.5) {
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
}
}
}
选择的解决方案有效,但它们也会将背景捕捉到顶部滚动位置。我扩展了上面的代码来修复那个“跳转”。
//Set 2 global variables
var scrollTopPosition = 0;
var lastKnownScrollTopPosition = 0;
//when the document loads
$(document).ready(function(){
//this only runs on the right platform -- this step is not necessary, it should work on all platforms
if( navigator.userAgent.match(/iPhone|iPad|iPod/i) ) {
//There is some css below that applies here
$('body').addClass('platform-ios');
//As you scroll, record the scrolltop position in global variable
$(window).scroll(function () {
scrollTopPosition = $(document).scrollTop();
});
//when the modal displays, set the top of the (now fixed position) body to force it to the stay in the same place
$('.modal').on('show.bs.modal', function () {
//scroll position is position, but top is negative
$('body').css('top', (scrollTopPosition * -1));
//save this number for later
lastKnownScrollTopPosition = scrollTopPosition;
});
//on modal hide
$('.modal').on('hidden.bs.modal', function () {
//force scroll the body back down to the right spot (you cannot just use scrollTopPosition, because it gets set to zero when the position of the body is changed by bootstrap
$('body').scrollTop(lastKnownScrollTopPosition);
});
}
});
CSS非常简单:
// You probably already have this, but just in case you don't
body.modal-open {
overflow: hidden;
width: 100%;
height: 100%;
}
//only on this platform does it need to be fixed as well
body.platform-ios.modal-open {
position: fixed;
}
如果你使用 jQuery,你可以使用scrollTop
#modal {
bottom: 0;
position: fixed;
overflow-y: scroll;
overflow-x: hidden;
top: 0;
width: 100%;
}
$('.open-modal').click(function (e) {
e.preventDefault();
$('#modal').toggle();
scrollTo = $('body').scrollTop();
$('body').css("position", "fixed");
});
$('.close-modal').click(function (e) {
e.preventDefault();
$('#modal').toggle();
$('body').css("position", "static");
$('body').animate({scrollTop: scrollTo}, 0);
});
上面的答案没有帮助,所以我所做的是:
.modal {
-webkit-overflow-scrolling: touch;
}
我的特殊问题是当我在加载后增加模态大小时。
这是一个已知的 iOS 问题,请参见此处。由于它不会破坏其他任何东西,因此上述解决方案足以满足我的需求。
对此也有问题,iPhone + Safari 需要添加:
position: fixed;
如其他地方所述,这造成了滚动到顶部的问题。对我有用的修复是在模态打开时捕获顶部的位置,然后在模态关闭时动画到该位置
在模态打开时:
scrollTo = $('body').scrollTop();
$('body').css("position", "fixed");
在模态关闭时
$('body').css("position", "static");
$('body').animate({scrollTop: scrollTo}, 0);
我想您可能会忘记向data-toggle="modal"
触发模式弹出事件的链接或按钮添加属性。首先,我也遇到了同样的问题,但是在添加上面的属性之后,它对我来说效果很好。
这可能有点像在这里打死马......但是,我目前通过 vanilla JS 在 DIY modals 上实现的解决方案:
在模态显示:
if (document.body.style.position !== 'fixed') {
document.body.style.top = -window.scrollY + 'px';
document.body.style.position = 'fixed';
}
在模态隐藏上:
document.body.style.position = '';
window.scrollTo(0, -parseInt(document.body.style.top, 10));
document.body.style.top = '';
我在模态之后打开了一个模态,并发现了模态滚动的错误,这个 css 解决了我的问题:
.modal {
overflow-y: auto;
padding-right: 15px;
}
我知道这已经得到解答,但这些解决方案都不适合我。我需要采取不同的方法。我正在使用 PhoneGap 并且正在本地编译我的代码,所以我不得不将背景移动到正文。我希望这对其他人有帮助。或者,如果有更清洁的方法可以做到这一点,请随时发表评论......
$(document).on('shown.bs.modal', '.modal', function (e) {
$("#" + e.target.id).find(".modal-backdrop").css("z-index", $("#" + e.target.id).css("z-index")).insertBefore("#" + e.target.id);
});
感谢JDiApice在iOS 8.x 模态滚动问题 #14839中综合并扩展了其他贡献者的工作:
@media only screen and (max-device-width:768px) {
body.modal-open {
// block scroll for mobile;
// causes underlying page to jump to top;
// prevents scrolling on all screens
overflow: hidden;
position: fixed;
}
}
body.viewport-lg {
// block scroll for desktop;
// will not jump to top;
// will not prevent scroll on mobile
position: absolute;
}
body {
overflow-x: hidden;
overflow-y: scroll !important;
}
/* The reason the media specific is on there is
on a desktop i was having issues with when the modal would open
all content on the page would shift from centered to left.
Looked like crap. So this targets up to tablet size devices
where you would need to scroll. There is still a slight shift
on mobile and tablet but its really not much. */
与我们尝试的其他解决方案不同,它不会在弹出模式关闭后将背景滚动到顶部。
作为来自引导文档的@Karthick Kumar 回答的补充
show在事件开始时触发
显示在动作完成时触发
...所以它应该是:
$('.modal')
.on('show.bs.modal', function (){
$('body').css('overflow', 'hidden');
})
.on('hide.bs.modal', function (){
// Also if you are using multiple modals (cascade) - additional check
if ($('.modal.in').length == 1) {
$('body').css('overflow', 'auto');
}
});
嘿伙计们,所以我想我找到了解决办法。目前,这对我在 iphone 和 android 上都有效。它是数小时搜索、阅读和测试的混搭。因此,如果您在这里看到您的部分代码,那么感谢您大声笑。
@media only screen and (max-device-width:768px){
body.modal-open {
// block scroll for mobile;
// causes underlying page to jump to top;
// prevents scrolling on all screens
overflow: hidden;
position: fixed;
}
}
body.viewport-lg {
// block scroll for desktop;
// will not jump to top;
// will not prevent scroll on mobile
position: absolute;
}
body {
overflow-x: hidden;
overflow-y: scroll !important;
}
特定媒体出现在桌面上的原因是,当模式打开页面上的所有内容时,我遇到了问题,它会从居中转移到左侧。看起来像废话。因此,这针对您需要滚动的平板电脑大小的设备。移动设备和平板电脑仍然有轻微的变化,但真的不多。让我知道这是否适合你们。希望这能把钉子钉在棺材上
使用position:fixed
具有将正文滚动到顶部的副作用。
如果您没有将身体滚动到顶部,请注意使用 position:fixed
. 如果模态打开,只需禁用 body 上的 touchmove。注意:模态本身仍然能够在触摸时滚动(如果大于屏幕)。
CSS:
body.modal-open {
overflow: hidden;
width: 100%;
/* NO position:fixed here*/
}
JS:
$('.modal').on('show.bs.modal', function (ev) { // prevent body from scrolling when modal opens
$('body').bind('touchmove', function(e){
if (!$(e.target).parents().hasClass( '.modal' )){ //only prevent touch move if it is not the modal
e.preventDefault()
}
})
})
$('.modal').on('hide.bs.modal', function (e) { //unbind the touchmove restrictions from body when modal closes
$('body').unbind('touchmove');
})
编辑:注意,对于非常小的模态,您可能必须将以下行添加到您的 CSS:
.modal-dialog{
height: 100%;
}
我找到了一个使用引导模式事件的简单 javascript/jquery 解决方案。
我的解决方案还解决了position:fixed
在打开/关闭模式窗口时将背景页面一直滚动到顶部而不是保持原位的问题。
在此处查看详细信息
我的解决方案...
//Fix modal mobile Boostrap 3
function Show(id){
//Fix CSS
$(".modal-footer").css({"padding":"19px 20px 20px","margin-top":"15px","text-align":"right","border-top":"1px solid #e5e5e5"});
$(".modal-body").css("overflow-y","auto");
//Fix .modal-body height
$('#'+id).on('shown.bs.modal',function(){
$("#"+id+">.modal-dialog>.modal-content>.modal-body").css("height","auto");
h1=$("#"+id+">.modal-dialog").height();
h2=$(window).height();
h3=$("#"+id+">.modal-dialog>.modal-content>.modal-body").height();
h4=h2-(h1-h3);
if($(window).width()>=768){
if(h1>h2){
$("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
}
$("#"+id+">.modal-dialog").css("margin","30px auto");
$("#"+id+">.modal-dialog>.modal-content").css("border","1px solid rgba(0,0,0,0.2)");
$("#"+id+">.modal-dialog>.modal-content").css("border-radius",6);
if($("#"+id+">.modal-dialog").height()+30>h2){
$("#"+id+">.modal-dialog").css("margin-top","0px");
$("#"+id+">.modal-dialog").css("margin-bottom","0px");
}
}
else{
//Fix full-screen in mobiles
$("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
$("#"+id+">.modal-dialog").css("margin",0);
$("#"+id+">.modal-dialog>.modal-content").css("border",0);
$("#"+id+">.modal-dialog>.modal-content").css("border-radius",0);
}
//Aply changes on screen resize (example: mobile orientation)
window.onresize=function(){
$("#"+id+">.modal-dialog>.modal-content>.modal-body").css("height","auto");
h1=$("#"+id+">.modal-dialog").height();
h2=$(window).height();
h3=$("#"+id+">.modal-dialog>.modal-content>.modal-body").height();
h4=h2-(h1-h3);
if($(window).width()>=768){
if(h1>h2){
$("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
}
$("#"+id+">.modal-dialog").css("margin","30px auto");
$("#"+id+">.modal-dialog>.modal-content").css("border","1px solid rgba(0,0,0,0.2)");
$("#"+id+">.modal-dialog>.modal-content").css("border-radius",6);
if($("#"+id+">.modal-dialog").height()+30>h2){
$("#"+id+">.modal-dialog").css("margin-top","0px");
$("#"+id+">.modal-dialog").css("margin-bottom","0px");
}
}
else{
//Fix full-screen in mobiles
$("#"+id+">.modal-dialog>.modal-content>.modal-body").height(h4);
$("#"+id+">.modal-dialog").css("margin",0);
$("#"+id+">.modal-dialog>.modal-content").css("border",0);
$("#"+id+">.modal-dialog>.modal-content").css("border-radius",0);
}
};
});
//Free event listener
$('#'+id).on('hide.bs.modal',function(){
window.onresize=function(){};
});
//Mobile haven't scrollbar, so this is touch event scrollbar implementation
var y1=0;
var y2=0;
var div=$("#"+id+">.modal-dialog>.modal-content>.modal-body")[0];
div.addEventListener("touchstart",function(event){
y1=event.touches[0].clientY;
});
div.addEventListener("touchmove",function(event){
event.preventDefault();
y2=event.touches[0].clientY;
var limite=div.scrollHeight-div.clientHeight;
var diff=div.scrollTop+y1-y2;
if(diff<0)diff=0;
if(diff>limite)diff=limite;
div.scrollTop=diff;
y1=y2;
});
//Fix position modal, scroll to top.
$('html, body').scrollTop(0);
//Show
$("#"+id).modal('show');
}