打开模态时防止BODY滚动

xor*_*zor 326 javascript css jquery scroll

当我的网站上的Modal(来自http://twitter.github.com/bootstrap)打开时,我希望我的身体在使用鼠标滚轮时停止滚动.

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

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

AND

$(window).live('scroll', function() { return false; });
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*nHN 455

当显示模式对话框时,Bootstrap会modal自动将类添加modal-open到正文中,并在隐藏对话框时将其删除.因此,您可以将以下内容添加到CSS:

body.modal-open {
    overflow: hidden;
}
Run Code Online (Sandbox Code Playgroud)

您可能会争辩说上面的代码属于Bootstrap CSS代码库,但这是一个简单的解决方法,可以将它添加到您的站点.

更新2013年2月8日
这已经停止在Twitter Boostrap v.2.3.0中工作 - 他们不再将该modal-open类添加到正文中.

解决方法是在将要显示模态时将类添加到正文,并在模式关闭时将其删除:

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

2013年3月11日更新 看起来这个modal-open类将在Bootstrap 3.0中返回,显式是为了防止滚动:

重新启动.modal-open在身体上(所以我们可以在那里核对滚动)

请参阅:https://github.com/twitter/bootstrap/pull/6342 - 查看模态部分.

  • 这在bootstrap 2.2.2中不再起作用.希望.modal-open将在未来回归... https://github.com/twitter/bootstrap/issues/5719 (2认同)
  • @ppetrid我不指望它会回来.基于这篇文章:https://github.com/twitter/bootstrap/wiki/Upcoming-3.0-changes(查看底部).引用:_"没有更多的内部模态滚动.相反,模态将增长以容纳其内容,页面滚动以容纳模态."_ (2认同)
  • @Bagata Cool - `modal-open`将在Bootstrap 3中返回,所以当它启动时,删除上面的代码应该是安全的. (2认同)
  • 这就是为什么人们应该继续向下滚动,如果所选择的答案不能满足你,那么你很可能会找到像这样的宝石.没有人期望在其他不那么喜欢的评论中,有97个以上的投票答案被埋没得如此之深. (2认同)
  • 这个问题是,为了防止文档在打开模态时滚动到顶部,你需要添加body.modal-open {overflow:visible}.您的解决方案目前正在工作,其缺点是,一旦模式开启,文档就会滚动到顶部 (2认同)

Bra*_*rad 114

接受的答案不适用于移动设备(至少iOS 7 w/Safari 7),我不希望CSS在我的网站上运行MOAR JavaScript.

此CSS将阻止背景页面在模式下滚动:

body.modal-open {
    overflow: hidden;
    position: fixed;
}
Run Code Online (Sandbox Code Playgroud)

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

如果你知道你的视口(我的插件用于添加视口<body>),你可以添加一个css切换position.

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; 
}
Run Code Online (Sandbox Code Playgroud)

我还添加了这个以防止底层页面在显示/隐藏模态时向左/向右跳跃.

body {
    // STOP MOVING AROUND!
    overflow-x: hidden;
    overflow-y: scroll !important;
}
Run Code Online (Sandbox Code Playgroud)

这个答案是一个x-post.

  • 谢谢!移动设备(至少是iOS和Android原生浏览器)让我头疼,如果没有身体上的"position:fixed",它就无法工作. (7认同)
  • 为了将滚动固定到顶部,您可以在添加类之前记录位置,然后在删除类之后,执行window.scroll到记录位置.这就是我为自己修复的方法:http://pastebin.com/Vpsz07zd. (6认同)

Meh*_*dız 30

只需隐藏身体溢出,它就会使身体不滚动.隐藏模态时,将其还原为自动模式.

这是代码:

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


cha*_*tfl 21

您可以尝试使用overflow设置体尺寸为窗口大小:当模态打开时隐藏

  • 这样做会在每次打开模态时移动屏幕,这不方便,我只需要禁用背景滚动 (11认同)
  • 它不是关于停止模态滚动,它是关于停止滚动背景中的身体 (7认同)
  • 它有效,但身体发生时会移动到顶部. (3认同)

mer*_*erv 17

警告:下面的选项与Bootstrap v3.0.x无关,因为这些版本中的滚动已明确局限于模态本身.如果禁用滚轮事件,可能会无意中阻止某些用户查看高度大于视口高度的模式中的内容.


另一种选择:车轮事件

滚动事件不是取消.但是可以取消鼠标滚轮滚轮事件.最重要的警告是,并非所有传统浏览器都支持它们,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');
  });
Run Code Online (Sandbox Code Playgroud)

的jsfiddle

  • 他们都在工作但不适用于移动设备.-__-测试了Android 4.1和Chrome (5认同)
  • 这不会阻止触摸设备滚动,`overflow:hidden`现在更好. (2认同)

jpa*_*pap 17

您需要超越@ charlietfl的答案和滚动条帐户,否则您可能会看到文档重排.

打开模态:

  1. 记录body宽度
  2. 设置body溢出到hidden
  3. 将主体宽度明确设置为步骤1中的宽度.

    var $body = $(document.body);
    var oldWidth = $body.innerWidth();
    $body.css("overflow", "hidden");
    $body.width(oldWidth);
    
    Run Code Online (Sandbox Code Playgroud)

关闭模态:

  1. 设置body溢出到auto
  2. 设置body宽度为auto

    var $body = $(document.body);
    $body.css("overflow", "auto");
    $body.width("auto");
    
    Run Code Online (Sandbox Code Playgroud)

灵感来自:http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php

  • @Hcabnettek 是的:“跳跃”==“文档重排”。很高兴它对你有帮助!:-) (2认同)

小智 9

/* =============================
 * 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(); });
});
Run Code Online (Sandbox Code Playgroud)


fat*_*Cop 9

试试这个:

.modal-open {
    overflow: hidden;
    position:fixed;
    width: 100%;
    height: 100%;
}
Run Code Online (Sandbox Code Playgroud)

它对我有用.(支持IE8)

  • 当你使用`position:fixed`打开模态时,这也可以让你跳到顶部. (2认同)

tet*_*suo 8

仅通过更改CSS无法使其在Chrome上运行,因为我不希望页面滚动回到顶部.这工作得很好:

$("#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);
});
Run Code Online (Sandbox Code Playgroud)


Clo*_*ick 8

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

  .body-no-scroll {
    height: 100vh;
    width: 100vw;
    touch-action: none;
    -webkit-overflow-scrolling: none;
    overflow: hidden;
    overscroll-behavior: none;
  }
Run Code Online (Sandbox Code Playgroud)


小智 7

添加类'is-modal-open'或使用javascript修改body标签的样式是可以的,它将按预期工作.但是我们要面对的问题是当身体变得溢出时:隐藏,它将跳到顶部,(scrollTop将变为0).这将在以后成为可用性问题.

作为此问题的解决方案,而不是更改正文标记溢出:隐藏在html标记上更改它

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


Mur*_*dız 7

对于引导,你可以试试这个(在工作FirefoxChromeMicrosoft Edge):

body.modal-open {
    overflow: hidden;
    position:fixed;
    width: 100%;
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助...


小智 7

反应,如果你正在寻找

弹出的模态中的 useEffect

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


Ani*_*pta 6

我不确定这个代码,但它值得一试.

在jQuery中:

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

正如我之前所说,我不是百分百肯定,但无论如何都要尝试.

  • 这不会阻止主体在打开模态时滚动 (2认同)

Ada*_*mJB 5

我不是 100% 确定这适用于 Bootstrap,但值得一试 - 它适用于 Remodal.js,可以在 github 上找到: http: //vodkabears.github.io/remodal/,这对于方法来说是有意义的非常相似。

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

body.with-modal {
    position: static;
    height: auto;
    overflow-y: hidden;
}
Run Code Online (Sandbox Code Playgroud)

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


use*_*118 5

截至2017年11月,Chrome推出了新的CSS属性

overscroll-behavior: contain;

尽管撰写本文时对跨浏览器的支持有限,但这解决了这个问题。

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

  • 2022 年,情况似乎会变得更好:https://caniuse.com/?search=overscroll-behavior (2认同)