当模式打开时,防止BODY滚动

我想我的身体停止滚动时,使用鼠标滚轮,而模式(从http://twitter.github.com/bootstrap)在我的网站是打开的。

当模式被打开时,我试图调用下面的javascript片段,但没有成功

$(window).scroll(function() { return false; });

$(window).live('scroll', function() { return false; });

请注意,我们的网站放弃了对IE6的支持,IE7+需要兼容。

650001 次浏览

你可以试着设置body size为window size, overflow:当modal打开时隐藏

我对这段代码不太确定,但值得一试。

jQuery:

$(document).ready(function() {
$(/* Put in your "onModalDisplay" here */)./* whatever */(function() {
$("#Modal").css("overflow", "hidden");
});
});

就像我之前说过的,我不是百分百确定,但还是试一试吧。

你可以使用下面的逻辑,我测试了它,它可以工作(即使在IE中)

   <html>


<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">


var currentScroll=0;
function lockscroll(){
$(window).scrollTop(currentScroll);
}




$(function(){


$('#locker').click(function(){
currentScroll=$(window).scrollTop();
$(window).bind('scroll',lockscroll);


})




$('#unlocker').click(function(){
currentScroll=$(window).scrollTop();
$(window).unbind('scroll');


})
})


</script>


<div>


<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<button id="locker">lock</button>
<button id="unlocker">unlock</button>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>


</div>

当模态对话框显示时,Bootstrap的modal自动将类modal-open添加到主体中,并在对话框隐藏时将其删除。因此,您可以在CSS中添加以下内容:

body.modal-open {
overflow: hidden;
}

你可能会说上面的代码属于Bootstrap CSS代码库,但这是一个简单的修复,可以将它添加到你的网站。

< p > 2013年2月8日更新 < br > 这在Twitter Bootstrap v. 2.3.0中已经停止工作——他们不再向主体添加modal-open

一个变通的方法是在模态即将显示时将类添加到主体中,并在模态关闭时将其删除:

$("#myModal").on("show", function () {
$("body").addClass("modal-open");
}).on("hidden", function () {
$("body").removeClass("modal-open")
});

更新2013年3月11日 看起来modal-open类将在Bootstrap 3.0中返回,显式地用于防止滚动:

在body上重新引入。modal-open(这样我们就可以把滚动移到这里)

看这个:https://github.com/twitter/bootstrap/pull/6342 -看模态部分。

简单地隐藏身体溢出,它使身体不滚动。隐藏模式时,将其恢复为自动模式。

代码如下:

$('#adminModal').modal().on('shown', function(){
$('body').css('overflow', 'hidden');
}).on('hidden', function(){
$('body').css('overflow', 'auto');
})

警告:下面的选项与Bootstrap v3.0无关。X,因为在这些版本中滚动被显式地限制在模态本身。如果禁用轮事件,可能会无意中阻止一些用户在高度大于视口高度的模态中查看内容。


还有另一个选择:车轮事件

滚动事件不可取消。然而,可以取消< >强mousewheel < / >强< >强轮< / >强事件。需要注意的是,并不是所有的传统浏览器都支持它们,Mozilla最近才在Gecko 17.0中添加了对后者的支持。我不知道它们的全部分布,但IE6+和Chrome确实支持它们。

下面是如何利用它们的方法:

$('#myModal')
.on('shown', function () {
$('body').on('wheel.modal mousewheel.modal', function () {
return false;
});
})
.on('hidden', function () {
$('body').off('wheel.modal mousewheel.modal');
});

< a href = " http://jsfiddle.net/mmfansler/qrKWq/ " > JSFiddle < / >

这招对我很管用:

$("#mymodal").mouseenter(function(){
$("body").css("overflow", "hidden");
}).mouseleave(function(){
$("body").css("overflow", "visible");
});

您需要超越@charlietfl的答案并考虑滚动条,否则您可能会看到一个文档回流。

打开模式:

  1. 记录body宽度
  2. body overflow设置为hidden
  3. 显式地将主体宽度设置为步骤1中的宽度。

    var $body = $(document.body);
    var oldWidth = $body.innerWidth();
    $body.css("overflow", "hidden");
    $body.width(oldWidth);
    

Closing the modal:

  1. Set body overflow to auto
  2. Set body width to auto

    var $body = $(document.body);
    $body.css("overflow", "auto");
    $body.width("auto");
    

Inspired by: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php

/* =============================
* Disable / Enable Page Scroll
* when Bootstrap Modals are
* shown / hidden
* ============================= */


function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}


function theMouseWheel(e) {
preventDefault(e);
}


function disable_scroll() {
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', theMouseWheel, false);
}
window.onmousewheel = document.onmousewheel = theMouseWheel;
}


function enable_scroll() {
if (window.removeEventListener) {
window.removeEventListener('DOMMouseScroll', theMouseWheel, false);
}
window.onmousewheel = document.onmousewheel = null;
}


$(function () {
// disable page scrolling when modal is shown
$(".modal").on('show', function () { disable_scroll(); });
// enable page scrolling when modal is hidden
$(".modal").on('hide', function () { enable_scroll(); });
});

HTML:

<body onscroll="stop_scroll()">

javascript:

function stop_scroll(){
scroll(0,0) ;
}

如果你在stop_scroll()中设置了标志(bool),你可以决定何时使用它(如果你只是暂时需要它)。

这将在每次某些元素溢出body边界并且窗口倾向于滚动时重置滚动(这完全独立于滚动条;overflow : hidden与此无关)。

最好的解决方案是大多数答案使用的css-only body{overflow:hidden}解决方案。一些答案提供了一个修复,也防止“跳跃”造成的消失滚动条;然而,没有一个太优雅。我写了这两个函数,它们看起来工作得很好。

var $body = $(window.document.body);


function bodyFreezeScroll() {
var bodyWidth = $body.innerWidth();
$body.css('overflow', 'hidden');
$body.css('marginRight', ($body.css('marginRight') ? '+=' : '') + ($body.innerWidth() - bodyWidth))
}


function bodyUnfreezeScroll() {
var bodyWidth = $body.innerWidth();
$body.css('marginRight', '-=' + (bodyWidth - $body.innerWidth()))
$body.css('overflow', 'auto');
}

查看这jsFiddle来查看它的使用。

大部分的片段都在这里,但我没有看到任何答案把它们放在一起。

这个问题有三个方面。

(1)防止底层页面滚动

$('body').css('overflow', 'hidden')

(2)并移除滚动条

var handler = function (e) { e.preventDefault() }
$('.modal').bind('mousewheel touchmove', handler)

(3)模态解散时进行清理

$('.modal').unbind('mousewheel touchmove', handler)
$('body').css('overflow', '')

如果模式不是全屏,那么将.modal绑定应用到全屏覆盖。

不能让它在Chrome上工作,只是通过改变CSS,因为我不想让页面滚动回顶部。这很有效:

$("#myModal").on("show.bs.modal", function () {
var top = $("body").scrollTop(); $("body").css('position','fixed').css('overflow','hidden').css('top',-top).css('width','100%').css('height',top+5000);
}).on("hide.bs.modal", function () {
var top = $("body").position().top; $("body").css('position','relative').css('overflow','auto').css('top',0).scrollTop(-top);
});

我对Bootstrap 3的解决方案:

.modal {
overflow-y: hidden;
}
body.modal-open {
margin-right: 0;
}

因为对我来说,body.modal-open类中唯一的overflow: hidden并没有因为原始的margin-right: 15px而阻止页面向左移动。

对于那些想知道如何获得滚动事件的引导3模态:

$(".modal").scroll(function() {
console.log("scrolling!);
});

接受的答案不工作在手机上(iOS 7 w/ Safari 7,至少),我不希望MOAR JavaScript运行在我的网站上,当CSS将做。

这个CSS将阻止后台页面在模式下滚动:

body.modal-open {
overflow: hidden;
position: fixed;
}

然而,它也有一个轻微的副作用,基本上是滚动到顶部。position:absolute解决了这个问题,但是重新引入了在移动设备上滚动的能力。

如果你知道你的视口(我的插件添加viewport到<body>),你可以为position添加一个css切换。

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 {
// STOP MOVING AROUND!
overflow-x: hidden;
overflow-y: scroll !important;
}

这个答案是一个x-post

这对我来说是最好的解决方案:

Css:

.modal {
overflow-y: auto !important;
}

Js:

modalShown = function () {
$('body').css('overflow', 'hidden');
},


modalHidden = function () {
$('body').css('overflow', 'auto');
}

我使用这个香草js函数添加“模态打开”类的身体。(根据smhmic的回答)

function freezeScroll(show, new_width)
{
var innerWidth = window.innerWidth,
clientWidth = document.documentElement.clientWidth,
new_margin = ((show) ? (new_width + innerWidth - clientWidth) : new_width) + "px";


document.body.style.marginRight = new_margin;
document.body.className = (show) ? "modal-open" : "";
};

隐藏溢出和固定位置的技巧,但在我的流体设计中,它会固定它超过浏览器宽度,所以宽度:100%固定。

body.modal-open{overflow:hidden;position:fixed;width:100%}

试试下面的代码:

$('.entry_details').dialog({
width:800,
height:500,
draggable: true,
title: entry.short_description,
closeText: "Zamknij",
open: function(){
//    blokowanie scrolla dla body
var body_scroll = $(window).scrollTop();
$(window).on('scroll', function(){
$(document).scrollTop(body_scroll);
});
},
close: function(){
$(window).off('scroll');
}
});

试试这个:

.modal-open {
overflow: hidden;
position:fixed;
width: 100%;
height: 100%;
}

这对我很管用。(支持IE8)

我刚才是这样做的……

$('body').css('overflow', 'hidden');

但当滚轮消失时,它将所有东西都正确移动了20px,所以我添加了

$('body').css('margin-right', '20px');

就在后面。

对我有用。

这个问题已经解决, 解决方案:只需打开bootstrap .css并更改如下

body.modal-open,
.modal-open .navbar-fixed-top,
.modal-open .navbar-fixed-bottom {
margin-right: 15px;
}

 body.modal-open,
.modal-open .navbar-fixed-top,
.modal-open .navbar-fixed-bottom {
/*margin-right: 15px;*/
}

请查看下面的youtube视频,只有不到3分钟,你的问题将解决… https://www.youtube.com/watch?v=kX7wPNMob_E < / p >

我不是100%确定这将与Bootstrap一起工作,但值得一试-它与momod .js一起工作,可以在github: http://vodkabears.github.io/remodal/上找到,它将有意义的方法非常相似。

为了阻止页面跳转到顶部并防止内容右移,在模态触发时向body添加一个类,并设置以下CSS规则:

body.with-modal {
position: static;
height: auto;
overflow-y: hidden;
}

position:staticheight:auto结合起来阻止内容向右跳转。overflow-y:hidden;阻止页面在模态后面可滚动。

你应该在HTML中添加overflow: hidden以获得更好的跨平台性能。

我会用

html.no-scroll {
overflow: hidden;
}
   $('.modal').on('shown.bs.modal', function (e) {
$('body').css('overflow-y', 'hidden');
});
$('.modal').on('hidden.bs.modal', function (e) {
$('body').css('overflow-y', '');
});

如果modal的高度/宽度为100%,“mouseenter/leave”可以很容易地启用/禁用滚动。这对我来说真的很管用:

var currentScroll=0;
function lockscroll(){
$(window).scrollTop(currentScroll);
}
$("#myModal").mouseenter(function(){
currentScroll=$(window).scrollTop();
$(window).bind('scroll',lockscroll);
}).mouseleave(function(){
currentScroll=$(window).scrollTop();
$(window).unbind('scroll',lockscroll);
});

基于此提琴:http://jsfiddle.net/dh834zgw/1/

下面的代码片段(使用jquery)将禁用窗口滚动:

 var curScrollTop = $(window).scrollTop();
$('html').toggleClass('noscroll').css('top', '-' + curScrollTop + 'px');

在你的css中:

html.noscroll{
position: fixed;
width: 100%;
top:0;
left: 0;
height: 100%;
overflow-y: scroll !important;
z-index: 10;
}

现在,当你删除模态时,不要忘记删除html标签上的noscroll类:

$('html').toggleClass('noscroll');

添加类'is-modal-open'或用javascript修改body标签的样式都是可以的,它会像预期的那样工作。但我们要面对的问题是当body变成overflow:hidden时,它会跳到顶部(scrollTop将变成0)。这将在以后成为一个可用性问题。

作为这个问题的解决方案,而不是改变正文标签溢出:隐藏改变它在html标签

$('#myModal').on('shown.bs.modal', function () {
$('html').css('overflow','hidden');
}).on('hidden.bs.modal', function() {
$('html').css('overflow','auto');
});

对于引导,你可以尝试这样做(在FirefoxChromeMicrosoft Edge上工作):

body.modal-open {
overflow: hidden;
position:fixed;
width: 100%;
}

希望这对你有所帮助……

对于那些使用SharePoint 2013的人,有一个小提示。主体已经有overflow: hidden。你要找的是在id为s4-workspace的div元素上设置overflow: hidden,例如。

var body = document.getElementById('s4-workspace');
body.className = body.className+" modal-open";

我有一个边栏,是由复选框黑客生成的。 但是主要的思想是保存文档scrollTop,而不是在滚动窗口时更改它

我只是不喜欢页面跳转时,身体变成'溢出:隐藏'。

window.addEventListener('load', function() {
let prevScrollTop = 0;
let isSidebarVisible = false;


document.getElementById('f-overlay-chkbx').addEventListener('change', (event) => {
        

prevScrollTop = window.pageYOffset || document.documentElement.scrollTop;
isSidebarVisible = event.target.checked;


window.addEventListener('scroll', (event) => {
if (isSidebarVisible) {
window.scrollTo(0, prevScrollTop);
}
});
})


});

为我工作

$('#myModal').on({'mousewheel': function(e)
{
if (e.target.id == 'el') return;
e.preventDefault();
e.stopPropagation();
}
});

不幸的是,上面的答案没有一个能解决我的问题。

在我的情况下,网页原本有一个滚动条。每当我点击模态,滚动条不会消失,标题会向右移动一点。

然后我尝试添加.modal-open{overflow:auto;}(大多数人推荐)。它确实解决了问题:滚动条出现后,我打开模式。然而,另一个副作用出现了,那就是“标题下面的背景会向左移动一点,在模态后面还有一个长条”

Long bar behind modal

幸运的是,在我添加{padding-right: 0 !important;}之后,一切都被完美地修复了。标题和正文背景都没有移动,模态仍然保持滚动条。

Fixed image

希望这可以帮助那些仍然被这个问题困扰的人。好运!

当你在另一个模态中使用一个模态时,就会发生上述情况。当我在另一个模态中打开一个模态时,后者的关闭将从body中删除类modal-open。这个问题的解决取决于你如何关闭后一个模式。

如果你用html关闭模态,

<button type="button" class="btn" data-dismiss="modal">Close</button>

然后你必须像这样添加一个监听器,

$(modalSelector).on("hidden.bs.modal", function (event) {
event.stopPropagation();
$("body").addClass("modal-open");
return false;
});

如果你用javascript关闭模态,

$(modalSelector).modal("hide");

然后你必须在一段时间后像这样运行命令,

setInterval(function(){$("body").addClass("modal-open");}, 300);

许多人建议在正文上使用“overflow: hidden”,这是行不通的(至少在我的情况下不是),因为它会让网站滚动到顶部。

这是适用于我的解决方案(手机和电脑),使用jQuery:

    $('.yourModalDiv').bind('mouseenter touchstart', function(e) {
var current = $(window).scrollTop();
$(window).scroll(function(event) {
$(window).scrollTop(current);
});
});
$('.yourModalDiv').bind('mouseleave touchend', function(e) {
$(window).off('scroll');
});

这将使模式的滚动工作,并防止网站在同一时间滚动。

2017年11月Chrome引入了一个新的css属性

overscroll-behavior: contain;

这解决了这个问题,尽管在编写时跨浏览器支持有限。

有关详细信息和浏览器支持,请参阅下面的链接

为什么不像Bulma那样做呢? 当modal is-active时,将它们的类.is-clipped添加到html中,即overflow: hidden!important;

编辑:好的,Bulma有这个bug,所以你必须添加其他东西,比如

html.is-modal-active {
overflow: hidden !important;
position: fixed;
width: 100%;
}

因为对我来说,这个问题主要出现在iOS上,所以我提供了只在iOS上修复的代码:

  if(!!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform)) {
var $modalRep    = $('#modal-id'),
startScrollY = null,
moveDiv;


$modalRep.on('touchmove', function(ev) {
ev.preventDefault();
moveDiv = startScrollY - ev.touches[0].clientY;
startScrollY = ev.touches[0].clientY;
var el = $(ev.target).parents('#div-that-scrolls');
// #div-that-scrolls is a child of #modal-id
el.scrollTop(el.scrollTop() + moveDiv);
});


$modalRep.on('touchstart', function(ev) {
startScrollY = ev.touches[0].clientY;
});
}

在StackOverflow上做了8-10个小时的研究后,我找到了一个可行的解决方案。

突破

$('.modal').is(':visible');

因此,我已经构建了一个函数来检查是否有任何模态是打开的,它会定期将类*modal-open**添加到

 setInterval(function()
{
if($('.modal').is(':visible')===true)
{
$("body").addClass("modal-open");
}
else
{
$("body").removeClass("modal-open");
}


},200);

这里使用$(“.modal”)的原因是因为所有的模态(在Bootstrap中)都使用类模态(淡出/显示是根据状态而定)。

所以我的模态现在运行完美没有身体得到滚动。

这在GitHub中也是一个bug/闻所未闻的问题,但没有人打扰。

以上的答案都不适合我。所以我找到了另一种行之有效的方法。

只需要添加一个scroll.(namespace)监听器,并将documentscrollTop设置为它的最新值…

并在关闭脚本中删除侦听器。

// in case of bootstrap modal example:
$('#myModal').on('shown.bs.modal', function () {
  

var documentScrollTop = $(document).scrollTop();
$(document).on('scroll.noScroll', function() {
$(document).scrollTop(documentScrollTop);
return false;
});


}).on('hidden.bs.modal', function() {


$(document).off('scroll.noScroll');


});

更新

似乎,这不是很好地工作在chrome。有什么建议吗?

这是

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

这是我的香草JS解决方案基于@jpap jquery:

let bodyElement = document.getElementsByTagName('body')[0];


// lock body scroll
let width = bodyElement.scrollWidth;
bodyElement.classList.add('overflow-hidden');
bodyElement.style.width = width + 'px';


// unlock body scroll
bodyElement.classList.remove('overflow-hidden');
bodyElement.style.width = 'auto';

反应,如果你在寻找

正在弹出的模态中的useEffect

 useEffect(() => {
document.body.style.overflowY = 'hidden';
return () =>{
document.body.style.overflowY = 'auto';
}
}, [])

我必须设置视口高度才能让它完美工作

body.modal-open {
height: 100vh;
overflow: hidden;
}

下面是我在React中修复这个问题的方法:

useEffect(() => {
if (isShown) {
const width = document.body.clientWidth;
document.body.style.overflow = "hidden";
document.body.style.width = `${width}px`;
} else {
document.body.style.overflow = "visible";
document.body.style.width = `auto`;
}


return () => {
document.body.style.overflow = "visible";
document.body.style.width = `auto`;
};
}, [isShown]);

我读的大多数答案都是关于React的。

我的React功能组件的最佳解决方案是使用最初由@arcticmatt提供的解决方案

我在下面的代码示例中包含了一些在其他答案中提到的改进(注意useEffect定义):

import {useEffect, useRef} from "react";


export default function PopoverMenu({className, handleClose, children}) {
const selfRef = useRef(undefined);


useEffect(() => {
const isPopoverOpenned = selfRef.current?.style.display !== "none";
const focusedElement = document?.activeElement;
const scrollPosition = {x: window.scrollX, y: window.scrollY};
if (isPopoverOpenned) {
preventDocBodyScrolling();
} else {
restoreDocBodyScrolling();
}


function preventDocBodyScrolling() {
const width = document.body.clientWidth;
const hasVerticalScrollBar = (window.innerWidth > document.documentElement.clientWidth);
document.body.style.overflowX = "hidden";
document.body.style.overflowY = hasVerticalScrollBar ? "scroll" : "";
document.body.style.width = `${width}px`;
document.body.style.position = "fixed";


}


function restoreDocBodyScrolling() {
document.body.style.overflowX = "";
document.body.style.overflowY = "";
document.body.style.width = "";
document.body.style.position = "";
focusedElement?.focus();
window.scrollTo(scrollPosition.x, scrollPosition.y);
}




return () => {
restoreDocBodyScrolling(); // cleanup on unmount
};
}, []);


return (
<>
<div
className="backdrop"
onClick={() => handleClose && handleClose()}
/>
<div
className={`pop-over-menu${className ? (` ${className}`) : ""}`}
ref={selfRef}
>
<button
className="pop-over-menu--close-button" type="button"
onClick={() => handleClose && handleClose()}
>
X
</button>
{children}
</div>
</>
);
}


这个解决方案对我很有效:

var scrollDistance = 0;
$(document).on("show.bs.modal", ".modal", function () {
scrollDistance = $(window).scrollTop();
$("body").css("top", scrollDistance * -1);
});


$(document).on("hidden.bs.modal", ".modal", function () {
$("body").css("top", "");
$(window).scrollTop(scrollDistance);
});
.content-area {
height: 750px;
background: grey;
text-align: center;
padding: 25px;
font-weight:700;
font-size: 30px;
}


body.modal-open {
position: fixed;
left: 0;
width: 100%;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.4.1.slim.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.js"></script>


<div class="content-area">
Scroll Down To Modal Button<br/>
<svg xmlns="http://www.w3.org/2000/svg" width="56" height="56" fill="currentColor" class="bi bi-arrow-down" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1z"/>
</svg>
</div>


<center class="my-3">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Launch demo modal
</button>
</center>




<div class="content-area"></div>




<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p>Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.</p>
<p>Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>

基本上,当打开模态时,它会为主体添加一个负顶部,以在打开模态之前保持窗口滚动位置。关闭模态时,窗口滚动保持使用相同的值应用于顶部时,打开。

.

.

这里是一个工作小提琴

现在是2022年,现在有了更好的CSS解决方案。这很有效。当模式打开时,您可以将这个类添加到body元素中,或者修改body样式本身。

  .body-no-scroll {
height: 100vh;
width: 100vw;
touch-action: none;
-webkit-overflow-scrolling: none;
overflow: hidden;
overscroll-behavior: none;
}

最著名的答案很简单,即。

body{
height: 100%;
overflow-y: hidden;
}

但是,如果你想在子/孙子中打开一个模态并停止滚动,该如何解决呢?更长期的解决方案是使用props或存储在Angular/React中,并改变body标签的高度和溢出属性。

另一种解决方案是通过从子/孙子组件获取主体,并相应地改变其高度和溢出以停止滚动。 在我的例子中,我只做了

if(isModalExpanded){
document.body.style.overflow = "hidden";
document.body.style.height = "100%";
}
else{
document.body.style.overflow = "auto";
document.body.style.height = "auto";
}