我试图禁用父母的html/身体滚动条,而我正在使用一个灯箱。这里的主要词是disable。我不想用溢出来隐藏它。
这样做的原因是overflow: hidden会使站点跳转并占用原来滚动的区域。
我想知道是否有可能禁用滚动条,同时仍然显示它。
我试图禁用父母的html/身体滚动条,而我正在使用一个灯箱。这里的主要词是disable。我不想用溢出来隐藏它。
这样做的原因是overflow: hidden会使站点跳转并占用原来滚动的区域。
我想知道是否有可能禁用滚动条,同时仍然显示它。
当前回答
另一个在固定模式上摆脱内容跳转的解决方案是,当删除主体滚动时,将页面宽度归一化:
body {width: 100vw; overflow-x: hidden;}
然后你可以玩固定位置或溢出:隐藏的身体时,模式是开放的。但它会隐藏水平滚动条-通常他们不需要响应式网站。
其他回答
你可以用Javascript来做:
// Classic JS
window.onscroll = function(ev) {
ev.preventDefault();
}
// jQuery
$(window).scroll(function(ev) {
ev.preventDefault();
}
然后当你的灯箱关闭时禁用它。
但如果你的灯箱包含滚动条,你将无法在它打开时滚动。这是因为window包含了body和#lightbox。 所以你必须使用像下面这样的架构:
<body>
<div id="global"></div>
<div id="lightbox"></div>
</body>
然后只在#global上应用onscroll事件。
位置:固定;解决方案有一个缺点-当应用此样式时,页面跳转到顶部。Angular的材质对话框有一个很好的解决方案,他们通过将定位应用到html元素来伪造滚动位置。
下面是我修改后的算法仅垂直滚动。左滚动块以完全相同的方式完成。
// This class applies the following styles:
// position: fixed;
// overflow-y: scroll;
// width: 100%;
const NO_SCROLL_CLASS = "bp-no-scroll";
const coerceCssPixelValue = value => {
if (value == null) {
return "";
}
return typeof value === "string" ? value : `${value}px`;
};
export const blockScroll = () => {
const html = document.documentElement;
const documentRect = html.getBoundingClientRect();
const { body } = document;
// Cache the current scroll position to be restored later.
const cachedScrollPosition =
-documentRect.top || body.scrollTop || window.scrollY || document.scrollTop || 0;
// Cache the current inline `top` value in case the user has set it.
const cachedHTMLTop = html.style.top || "";
// Using `html` instead of `body`, because `body` may have a user agent margin,
// whereas `html` is guaranteed not to have one.
html.style.top = coerceCssPixelValue(-cachedScrollPosition);
// Set the magic class.
html.classList.add(NO_SCROLL_CLASS);
// Return a function to remove the scroll block.
return () => {
const htmlStyle = html.style;
const bodyStyle = body.style;
// We will need to seamlessly restore the original scroll position using
// `window.scroll`. To do that we will change the scroll behavior to `auto`.
// Here we cache the current scroll behavior to restore it later.
const previousHtmlScrollBehavior = htmlStyle.scrollBehavior || "";
const previousBodyScrollBehavior = bodyStyle.scrollBehavior || "";
// Restore the original inline `top` value.
htmlStyle.top = cachedHTMLTop;
// Remove the magic class.
html.classList.remove(NO_SCROLL_CLASS);
// Disable user-defined smooth scrolling temporarily while we restore the scroll position.
htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = "auto";
// Restore the original scroll position.
window.scroll({
top: cachedScrollPosition.top
});
// Restore the original scroll behavior.
htmlStyle.scrollBehavior = previousHtmlScrollBehavior;
bodyStyle.scrollBehavior = previousBodyScrollBehavior;
};
};
逻辑非常简单,如果不考虑某些边界情况,还可以进一步简化。例如,这是我使用的:
export const blockScroll = () => {
const html = document.documentElement;
const documentRect = html.getBoundingClientRect();
const { body } = document;
const screenHeight = window.innerHeight;
// Only do the magic if document is scrollable
if (documentRect.height > screenHeight) {
const cachedScrollPosition =
-documentRect.top || body.scrollTop || window.scrollY || document.scrollTop || 0;
html.style.top = coerceCssPixelValue(-cachedScrollPosition);
html.classList.add(NO_SCROLL_CLASS);
return () => {
html.classList.remove(NO_SCROLL_CLASS);
window.scroll({
top: cachedScrollPosition,
behavior: "auto"
});
};
}
};
你不能禁用滚动事件,但是你可以禁用导致滚动的相关操作,比如鼠标滚轮和touchmove:
$('body').on('mousewheel touchmove', function(e) {
e.preventDefault();
});
在公认的解决方案基础上增加了四个小补充:
Apply 'noscroll' to html instead of to body to prevent double scroll bars in IE To check if there's actually a scroll bar before adding the 'noscroll' class. Otherwise, the site will also jump pushed by the new non-scrolling scroll bar. To keep any possible scrollTop so 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
完整的解决方案,似乎适用于大多数浏览器:
CSS
html.noscroll {
position: fixed;
overflow-y: scroll;
width: 100%;
}
禁用滚动
if ($(document).height() > $(window).height()) {
var scrollTop = ($('html').scrollTop()) ? $('html').scrollTop() : $('body').scrollTop(); // Works for Chrome, Firefox, IE...
$('html').addClass('noscroll').css('top',-scrollTop);
}
启用滚动
var scrollTop = parseInt($('html').css('top'));
$('html').removeClass('noscroll');
$('html,body').scrollTop(-scrollTop);
感谢法布里齐奥和德扬把我带到了正确的轨道上,感谢布罗丁戈解决了双滚动条的问题
如果覆盖层下的页面可以“固定”在顶部,当你打开覆盖层时,你可以设置
.disableScroll { position: fixed; overflow-y:scroll }
将这个类提供给可滚动的主体,您仍然应该看到正确的滚动条,但内容是不可滚动的。
用jquery来保持页面的位置
$('body').css('top', - ($(window).scrollTop()) + 'px').addClass('disableScroll');
当你关闭覆盖时,只需恢复这些属性
var top = $('body').position().top;
$('body').removeClass('disableScroll').css('top', 0).scrollTop(Math.abs(top));
我之所以建议采用这种方式,只是因为您不需要更改任何滚动事件