打开模式时防止滚动

ynulla 发布于 2018-12-29 javascript 最后更新 2018-12-29 08:02 37 浏览

当我的网站上的Modal(来自http://twitter.github.com/bootstrap)打开时,我希望我的身体在使用鼠标滚轮时停止滚动。 当模式打开但我没有成功时,我试图调用下面的那段javascript

$(window).scroll(function() { return false; });
AND
$(window).live('scroll', function() { return false; });
请注意我们的网站放弃了对IE6的支持,但IE7需要兼容。
已邀请:

psequi

赞同来自:

我这样做了......

$('body').css('overflow', 'hidden');
但是当卷轴消失时它将所有东西都移动了20px,所以我补充道
$('body').css('margin-right', '20px');
在它之后。 适合我。

paut

赞同来自:

您可以使用以下逻辑,我测试它并且它可以工作(即使在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>

iqui

赞同来自:

我的Bootstrap 3解决方案:

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

onam

赞同来自:

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


又一个选项:车轮事件 滚动事件不可取消。但是,可以取消mousewheelwheel事件。最重要的一点是,并非所有传统浏览器都支持它们,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');
  });

JSFiddle

uanimi

赞同来自:

只需隐藏身体溢出,它就会使身体不滚动。隐藏模态时,将其还原为自动模式。 这是代码:

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

xatque

赞同来自:

对于那些想知道如何获得bootstrap 3模式的滚动事件的人:

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

weos

赞同来自:

可悲的是,上述答案都没有解决我的问题。 在我的情况下,网页最初有一个滚动条。每当我点击模态时,滚动条都不会消失,标题会向右移动一点。 然后我尝试添加.modal-open{overflow:auto;}(大多数人推荐)。它确实修复了问题:打开模态后出现滚动条。然而,出现了另一个副作用,即“标题下方的背景将向左移动一点,以及模态后面的另一个长条” Long bar behind modal 幸运的是,在我添加{padding-right: 0 !important;}之后,一切都完美无缺。标题和正文背景都没有移动,模态仍保留滚动条。 Fixed image 希望这可以帮助那些仍然坚持这个问题的人。祝你好运!

bea

赞同来自:

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

打开模态:
  1. 记录body宽度
  2. body溢出设置为hidden
  3. 将身体宽度明确设置为步骤1中的宽度。
var $body = $(document.body);
var oldWidth = $body.innerWidth();
$body.css("overflow", "hidden");
$body.width(oldWidth);

关闭模态:
  1. body溢出设为auto
  2. body宽度设为auto
var $body = $(document.body);
$body.css("overflow", "auto");
$body.width("auto");
灵感来自:http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php

dsit

赞同来自:

/* =============================
 * 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(); });
});

svelit

赞同来自:

我有一个由复选框黑客生成的侧边栏。 但主要的想法是保存文档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);
            }
        });
    })
});

uut

赞同来自:

我正在使用这个vanilla js函数向主体添加“modal-open”类。 (根据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" : "";
};

vsit

赞同来自:

我不是100%肯定这将适用于Bootstrap但值得一试 - 它适用于可以在github上找到的Remodal.js:http://vodkabears.github.io/remodal/并且这些方法非常相似是有意义的。 要阻止页面跳到顶部并阻止内容的右移,在触发模式时将类添加到body并设置以下CSS规则:

body.with-modal {
    position: static;
    height: auto;
    overflow-y: hidden;
}
它是position:staticheight:auto,它们结合起来阻止内容向右跳跃。 overflow-y:hidden;阻止页面在模态后面滚动。

wiusto

赞同来自:

最好的解决方案是大多数答案使用的仅限CSS的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');
}
查看this jsFiddle以查看其中的使用情况。

cet

赞同来自:

我不确定这个代码,但它值得一试。 在jQuery中:

$(document).ready(function() {
    $(/* Put in your "onModalDisplay" here */)./* whatever */(function() {
        $("#Modal").css("overflow", "hidden");
    });
});
正如我之前所说,我不是百分百肯定,但无论如何都要尝试。

cut

赞同来自:

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

html.no-scroll {
    overflow: hidden;
}

dodit

赞同来自:

接受的答案不适用于移动设备(至少iOS 7 w / Safari 7),我不希望CSS在我的网站上运行MOAR JavaScript。 此CSS将阻止背景页面在模式下滚动:

body.modal-open {
    overflow: hidden;
    position: fixed;
}
但是,它也有一个轻微的副作用,基本上滚动到顶部。 position:absolute解决了这个问题,但重新介绍了在移动设备上滚动的功能。 如果您知道视口(my plugin for adding viewport to the <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;
}
this answer is a x-post.

jalias

赞同来自:

对于Bootstrap 3,您可以尝试这个(处理FirefoxChromeMicrosoft Edge):

body.modal-open {
    overflow: hidden;
    position:fixed;
    width: 100%;
}
希望这可以帮助...

jautem

赞同来自:

SharePoint 2013中的小注释。正文已有overflow: hidden。你要找的是在id元素s4-workspace的div元素上设置overflow: hidden,例如

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

bsit

赞同来自:

为我工作

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

dsed

赞同来自:

大多数作品都在这里,但我没有看到任何答案将它们放在一起。 问题是三重的。 (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绑定应用于全屏叠加。

nodio

赞同来自:

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

.modal {
     overflow-y: auto !important;
}
和Js:
modalShown = function () {
    $('body').css('overflow', 'hidden');
},
modalHidden = function () {
    $('body').css('overflow', 'auto');
}

yut

赞同来自:

添加类'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');
});

dsed

赞同来自:

试试这段代码:

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

noptio

赞同来自:

试试这个:

.modal-open {
    overflow: hidden;
    position:fixed;
    width: 100%;
    height: 100%;
}
它对我有用。 (支持IE8)

yet

赞同来自:

许多建议身体上的“溢出:隐藏”,这将无法工作(至少在我的情况下),因为它将使网站滚动到顶部。 这是适用于我的解决方案(包括手机和计算机),使用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');
    });
这将使模式的滚动起作用,并防止网站同时滚动。

het

赞同来自:

这个问题是固定的, 解决方案:只需打开bootstap.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

wnatus

赞同来自:

基于这个小提琴: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');

yeum

赞同来自:

这对我有用:

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

et_id

赞同来自:

HTML:

<body onscroll="stop_scroll()">
JavaScript的:
function stop_scroll(){
    scroll(0,0) ;
}
如果您在stop_scroll()中设置了一个标志(bool),您可以决定何时参与(如果您只想临时使​​用)。 每当一些元素溢出body边界并且窗口倾向于滚动时,这将重置滚动(这完全独立于滚动条; overflow : hidden与它无关)。

taut

赞同来自:

当您在另一个模态中使用模态时会发生上述情况。当我在另一个模态中打开模态时,后者的关闭会从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);

cea

赞同来自:

隐藏溢出并固定位置可以解决问题,但是通过我的流体设计,它可以将其固定在浏览器宽度之外,因此宽度:100%固定。

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

et_et

赞同来自:

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

zsed

赞同来自:

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

body.modal-open {
    overflow: hidden;
}
您可能会争辩说上面的代码属于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")
});
2013年3月11日更新 看起来modal-open类将在Bootstrap 3.0中返回,显式是为了防止滚动:
Reintroduces .modal-open on the body (so we can nuke the scroll there)
请参阅:https://github.com/twitter/bootstrap/pull/6342 - 查看模态部分。

funde

赞同来自:

如果模态是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); 
});

yquo

赞同来自:

仅通过更改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);
});

rvero

赞同来自:

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

要回复问题请先登录注册