Javascript 只是禁用滚动而不是隐藏它?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8701754/
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
Just disable scroll not hide it?
提问by Dejan.S
I'm trying to disable the html/body scrollbar of the parent while I'm using a lightbox. The main word here is disable. I do notwant to hide it with overflow: hidden;
.
我正在尝试在使用灯箱时禁用父级的 html/body 滚动条。这里的主要词是disable。我也没有想隐藏它overflow: hidden;
。
The reason for this is that overflow: hidden
makes the site jump and take up the area where the scroll was.
这样做的原因是overflow: hidden
使站点跳跃并占据滚动所在的区域。
I want to know if its possible to disable a scrollbar while still showing it.
我想知道是否可以在仍然显示滚动条的同时禁用它。
采纳答案by Fabrizio Calderan
If the page under the overlayer can be "fixed" at the top, when you open the overlay you can set
如果overlayer下的页面可以“固定”在顶部,当你打开overlay时可以设置
body { position: fixed; overflow-y:scroll }
you should still see the right scrollbar but the content is not scrollable. When you close the overlay just revert these properties with
您仍然应该看到正确的滚动条,但内容不可滚动。当您关闭叠加层时,只需使用以下命令还原这些属性
body { position: static; overflow-y:auto }
I just proposed this way only because you wouldn't need to change any scroll event
我提出这种方式只是因为您不需要更改任何滚动事件
Update
更新
You could also do a slight improvement: if you get the document.documentElement.scrollTop
property via javascript just before the layer opening, you could dynamically assign that value as top
property of the body element: with this approach the page will stand in its place, no matter if you're on top or if you have already scrolled.
您还可以做一点改进:如果您document.documentElement.scrollTop
在图层打开之前通过 javascript获取该属性,您可以将该值动态分配为top
body 元素的属性:使用这种方法,页面将保持原位,无论您是否“重新在顶部或者如果您已经滚动。
Css
css
.noscroll { position: fixed; overflow-y:scroll }
JS
JS
$('body').css('top', -(document.documentElement.scrollTop) + 'px')
.addClass('noscroll');
回答by Mike Garcia
Four little additions to the selected solution:
所选解决方案的四个小补充:
- Apply 'noscroll' to html instead of to bodyto prevent double scroll bars in IE
- To check if there's actually a scroll barbefore adding the 'noscroll' class. Otherwise, the site will also jump pushed by the new non-scrolling scroll bar.
- To keep any possible scrollTopso the entire page doesn't go back to the top (like Fabrizio's update, but you need to grab the value before adding the 'noscroll' class)
- Not all browsers handle scrollTop the same way as documented at http://help.dottoro.com/ljnvjiow.php
- 将 'noscroll' 应用于html 而不是 body以防止 IE 中的双滚动条
- 要检查是否确实有一个滚动条增加了“noscroll”课前。否则,网站也会被新的非滚动滚动条跳转推送。
- 保留任何可能的scrollTop以便整个页面不会回到顶部(如 Fabrizio 的更新,但您需要在添加 'noscroll' 类之前获取该值)
- 并非所有浏览器都以http://help.dottoro.com/ljnvjiow.php 中记录的相同方式处理 scrollTop
Complete solution that seems to work for most browsers:
似乎适用于大多数浏览器的完整解决方案:
CSS
CSS
html.noscroll {
position: fixed;
overflow-y: scroll;
width: 100%;
}
Disable scroll
禁用滚动
if ($(document).height() > $(window).height()) {
var scrollTop = ($('html').scrollTop()) ? $('html').scrollTop() : $('body').scrollTop(); // Works for Chrome, Firefox, IE...
$('html').addClass('noscroll').css('top',-scrollTop);
}
Enable scroll
启用滚动
var scrollTop = parseInt($('html').css('top'));
$('html').removeClass('noscroll');
$('html,body').scrollTop(-scrollTop);
Thanks to Fabrizio and Dejan for putting me on the right track and to Brodingo for the solution to the double scroll bar
感谢 Fabrizio 和 Dejan 让我走上正轨,感谢 Brodingo解决双滚动条
回答by ceed
With jQuery inluded:
包含 jQuery:
disable
禁用
$.fn.disableScroll = function() {
window.oldScrollPos = $(window).scrollTop();
$(window).on('scroll.scrolldisabler',function ( event ) {
$(window).scrollTop( window.oldScrollPos );
event.preventDefault();
});
};
enable
使能够
$.fn.enableScroll = function() {
$(window).off('scroll.scrolldisabler');
};
usage
用法
//disable
$("#selector").disableScroll();
//enable
$("#selector").enableScroll();
回答by Dejan.S
I'm the OP
我是 OP
With the help of answer from fcalderan I was able to form a solution. I leave my solution here as it brings clarity to how to use it, and adds a very crucial detail, width: 100%;
在 fcalderan 的回答的帮助下,我能够形成一个解决方案。我把我的解决方案留在这里,因为它让我清楚地知道如何使用它,并添加了一个非常关键的细节,width: 100%;
I add this class
我添加这个类
body.noscroll
{
position: fixed;
overflow-y: scroll;
width: 100%;
}
this worked for me and I was using Fancyapp.
这对我有用,我正在使用 Fancyapp。
回答by dmackenz
This worked really well for me....
这对我来说非常有效......
// disable scrolling
$('body').bind('mousewheel touchmove', lockScroll);
// enable scrolling
$('body').unbind('mousewheel touchmove', lockScroll);
// lock window scrolling
function lockScroll(e) {
e.preventDefault();
}
just wrap those two lines of code with whatever decides when you are going to lock scrolling.
只需用决定何时锁定滚动的任何内容包装这两行代码即可。
e.g.
例如
$('button').on('click', function() {
$('body').bind('mousewheel touchmove', lockScroll);
});
回答by tocqueville
You cannot disable the scroll event, but you can disable the related actions that lead to a scroll, like mousewheel and touchmove:
您不能禁用滚动事件,但可以禁用导致滚动的相关操作,例如鼠标滚轮和触摸移动:
$('body').on('mousewheel touchmove', function(e) {
e.preventDefault();
});
回答by mpen
You can hide the body's scrollbar with overflow: hidden
and set a margin at the same time so that the content doesn't jump:
您可以隐藏主体的滚动条并overflow: hidden
同时设置边距,以便内容不会跳转:
let marginRightPx = 0;
if(window.getComputedStyle) {
let bodyStyle = window.getComputedStyle(document.body);
if(bodyStyle) {
marginRightPx = parseInt(bodyStyle.marginRight, 10);
}
}
let scrollbarWidthPx = window.innerWidth - document.body.clientWidth;
Object.assign(document.body.style, {
overflow: 'hidden',
marginRight: `${marginRightPx + scrollbarWidthPx}px`
});
And then you can add a disabled scrollbar to the page to fill in the gap:
然后你可以在页面上添加一个禁用的滚动条来填补空白:
textarea {
overflow-y: scroll;
overflow-x: hidden;
width: 11px;
outline: none;
resize: none;
position: fixed;
top: 0;
right: 0;
bottom: 0;
border: 0;
}
<textarea></textarea>
I did exactly this for my own lightbox implementation. Seems to be working well so far.
我正是为了我自己的灯箱实现而这样做的。到目前为止似乎运作良好。
回答by 0b10011
This is the solution we went with. Simply save the scroll position when the overlay is opened, scroll back to the saved position any time the user attempted to scroll the page, and turn the listener off when the overlay is closed.
这是我们采用的解决方案。只需在打开覆盖层时保存滚动位置,在用户尝试滚动页面时随时滚动回保存的位置,并在覆盖层关闭时关闭侦听器。
It's a bit jumpy on IE, but works like a charm on Firefox/Chrome.
它在 IE 上有点跳动,但在 Firefox/Chrome 上就像一个魅力。
var body = $("body"),
overlay = $("#overlay"),
overlayShown = false,
overlayScrollListener = null,
overlaySavedScrollTop = 0,
overlaySavedScrollLeft = 0;
function showOverlay() {
overlayShown = true;
// Show overlay
overlay.addClass("overlay-shown");
// Save scroll position
overlaySavedScrollTop = body.scrollTop();
overlaySavedScrollLeft = body.scrollLeft();
// Listen for scroll event
overlayScrollListener = body.scroll(function() {
// Scroll back to saved position
body.scrollTop(overlaySavedScrollTop);
body.scrollLeft(overlaySavedScrollLeft);
});
}
function hideOverlay() {
overlayShown = false;
// Hide overlay
overlay.removeClass("overlay-shown");
// Turn scroll listener off
if (overlayScrollListener) {
overlayScrollListener.off();
overlayScrollListener = null;
}
}
// Click toggles overlay
$(window).click(function() {
if (!overlayShown) {
showOverlay();
} else {
hideOverlay();
}
});
/* Required */
html, body { margin: 0; padding: 0; height: 100%; background: #fff; }
html { overflow: hidden; }
body { overflow-y: scroll; }
/* Just for looks */
.spacer { height: 300%; background: orange; background: linear-gradient(#ff0, #f0f); }
.overlay { position: fixed; top: 20px; bottom: 20px; left: 20px; right: 20px; z-index: -1; background: #fff; box-shadow: 0 0 5px rgba(0, 0, 0, .3); overflow: auto; }
.overlay .spacer { background: linear-gradient(#88f, #0ff); }
.overlay-shown { z-index: 1; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1>Top of page</h1>
<p>Click to toggle overlay. (This is only scrollable when overlay is <em>not</em> open.)</p>
<div class="spacer"></div>
<h1>Bottom of page</h1>
<div id="overlay" class="overlay">
<h1>Top of overlay</h1>
<p>Click to toggle overlay. (Containing page is no longer scrollable, but this is.)</p>
<div class="spacer"></div>
<h1>Bottom of overlay</h1>
</div>
回答by dhc
I had a similar problem: a left-hand menu that, when it appears, prevents scrolling. As soon as height was set to 100vh, the scrollbar disappeared and the content jerked to the right.
我遇到了类似的问题:出现时会阻止滚动的左侧菜单。一旦高度设置为 100vh,滚动条就消失了,内容向右猛拉。
So if you don't mind keeping the scrollbar enabled (but setting the window to full height so it won't actually scroll anywhere) then another possibility is setting a tiny bottom margin, which will keep the scroll bars showing:
因此,如果您不介意启用滚动条(但将窗口设置为全高,因此它实际上不会滚动到任何地方),那么另一种可能性是设置一个很小的底部边距,这将使滚动条保持显示:
body {
height: 100vh;
overflow: hidden;
margin: 0 0 1px;
}
回答by Marek C
<div id="lightbox">
is inside the <body>
element, thus when you scroll the lightbox you also scroll the body. The solution is to not extend the <body>
element over 100%, to place the long content inside another div
element and to add a scrollbar if needed to this div
element with overflow: auto
.
<div id="lightbox">
位于<body>
元素内部,因此当您滚动灯箱时,您也会滚动正文。解决方案是不要将<body>
元素扩展到100% 以上,将长内容放置在另一个div
元素中,并在需要时div
使用overflow: auto
.
html {
height: 100%
}
body {
margin: 0;
height: 100%
}
#content {
height: 100%;
overflow: auto;
}
#lightbox {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
<html>
<body>
<div id="content">much content</div>
<div id="lightbox">lightbox<div>
</body>
</html>
Now, scrolling over the lightbox (and the body
as well) has no effect, because the body is no longer than 100% of the screen height.
现在,滚动灯箱(以及灯箱body
)没有任何效果,因为主体不超过屏幕高度的 100%。