我试图禁用父母的html/身体滚动条,而我正在使用一个灯箱。这里的主要词是disable。我不想用溢出来隐藏它。
这样做的原因是overflow: hidden会使站点跳转并占用原来滚动的区域。
我想知道是否有可能禁用滚动条,同时仍然显示它。
我试图禁用父母的html/身体滚动条,而我正在使用一个灯箱。这里的主要词是disable。我不想用溢出来隐藏它。
这样做的原因是overflow: hidden会使站点跳转并占用原来滚动的区域。
我想知道是否有可能禁用滚动条,同时仍然显示它。
当前回答
你可以保持overflow:隐藏,但手动管理滚动位置:
在显示实际滚动位置之前保持跟踪:
var scroll = [$(document).scrollTop(),$(document).scrollLeft()];
//show your lightbox and then reapply scroll position
$(document).scrollTop(scroll[0]).scrollLeft(scroll[1]);
应该可以
其他回答
所有基于javascript的modal/lightbox系统在html标签或body标签上显示modal/lightbox时都会使用溢出。
当lightbox显示时,js会推送一个隐藏在html或body标签上的溢出。 当lightbox被隐藏时,有些人会删除隐藏的,有些人会在html或body标签上推一个溢出自动。
在Mac上工作的开发人员没有看到滚动条的问题。
只需替换隐藏的unset不看到内容滑动下的模式删除滚动条。
Lightbox开放/显示:
<html style="overflow: unset;"></html>
Lightbox隐藏/关闭:
<html style="overflow: auto;"></html>
我喜欢坚持使用“overflow: hidden”方法,只需添加与滚动条宽度相等的右填充。
通过lostsource获取滚动条宽度函数。
function getScrollbarWidth() {
var outer = document.createElement("div");
outer.style.visibility = "hidden";
outer.style.width = "100px";
outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
document.body.appendChild(outer);
var widthNoScroll = outer.offsetWidth;
// force scrollbars
outer.style.overflow = "scroll";
// add innerdiv
var inner = document.createElement("div");
inner.style.width = "100%";
outer.appendChild(inner);
var widthWithScroll = inner.offsetWidth;
// remove divs
outer.parentNode.removeChild(outer);
return widthNoScroll - widthWithScroll;
}
当显示覆盖时,在html中添加"noscroll"类,并在body中添加padding-right:
$(html).addClass("noscroll");
$(body).css("paddingRight", getScrollbarWidth() + "px");
当隐藏时,删除类和填充:
$(html).removeClass("noscroll");
$(body).css("paddingRight", 0);
noscroll样式是这样的:
.noscroll { overflow: hidden; }
注意,如果你有任何带有position:fixed的元素,你也需要为这些元素添加填充。
我有一些其他固定的元素在页面和设置主体的位置固定导致了一堆其他问题,所以我做了一个hack的方式:
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
// on opening modal
document.body.style.overflow = "hidden"
document.body.style.paddingRight = `${scrollbarWidth}px`
// on closing modal
document.body.style.overflow = "unset",
document.body.style.paddingRight = "0px"
这个想法是添加一个与浏览器滚动条宽度相同的右填充,以模仿假滚动条并防止内容移动。
在公认的解决方案基础上增加了四个小补充:
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);
感谢法布里齐奥和德扬把我带到了正确的轨道上,感谢布罗丁戈解决了双滚动条的问题
位置:固定;解决方案有一个缺点-当应用此样式时,页面跳转到顶部。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"
});
};
}
};