我正在尝试使用灯箱时禁用父级的html / body滚动条。这里的主要词是 disable。我也没有想隐藏它overflow: hidden;
。
这样做的原因是overflow: hidden
使站点跳转并占据了滚动所在的区域。
我想知道是否有可能在仍然显示它的同时禁用滚动条。
我正在尝试使用灯箱时禁用父级的html / body滚动条。这里的主要词是 disable。我也没有想隐藏它overflow: hidden;
。
这样做的原因是overflow: hidden
使站点跳转并占据了滚动所在的区域。
我想知道是否有可能在仍然显示它的同时禁用滚动条。
Answers:
如果覆盖层下的页面可以在顶部“固定”,则在打开覆盖层时可以设置
body { position: fixed; overflow-y:scroll }
您仍应看到右侧的滚动条,但内容不可滚动。当您关闭叠加层时,只需还原这些属性即可
body { position: static; overflow-y:auto }
我只是以这种方式提出了建议,因为您不需要更改任何滚动事件
更新资料
您还可以做些微的改进:如果您document.documentElement.scrollTop
在打开图层之前通过javascript 获得该属性,则可以将该值动态分配为top
body元素的属性:通过这种方法,无论您是否将页面放置在原处,重新放在顶部或您是否已经滚动。
的CSS
.noscroll { position: fixed; overflow-y:scroll }
JS
$('body').css('top', -(document.documentElement.scrollTop) + 'px')
.addClass('noscroll');
$('body').css('top', -($('body').scrollTop()) + 'px').addClass('noscroll');
所选解决方案的四个小补充:
似乎适用于大多数浏览器的完整解决方案:
的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);
afterLoad()
和afterClose
回调禁用灯箱图像的滚动。对于其他搜索此问题的人可能有用。
scrollTop
,因此“禁用滚动”代码的第2行可以表示为$( window ).scrollTop()
。
if (scrollTop < 0) { scrollTop = 0; }
。这是禁用gist.github.com/jayd3e/2eefbbc571cd1668544b的完整代码。
$.fn.disableScroll = function() {
window.oldScrollPos = $(window).scrollTop();
$(window).on('scroll.scrolldisabler',function ( event ) {
$(window).scrollTop( window.oldScrollPos );
event.preventDefault();
});
};
$.fn.enableScroll = function() {
$(window).off('scroll.scrolldisabler');
};
//disable
$("#selector").disableScroll();
//enable
$("#selector").enableScroll();
这对我来说真的很好。
// disable scrolling
$('body').bind('mousewheel touchmove', lockScroll);
// enable scrolling
$('body').unbind('mousewheel touchmove', lockScroll);
// lock window scrolling
function lockScroll(e) {
e.preventDefault();
}
只需将这两行代码包装在一起即可决定何时锁定滚动。
例如
$('button').on('click', function() {
$('body').bind('mousewheel touchmove', lockScroll);
});
您可以使用隐藏实体的滚动条并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`
});
然后,您可以向页面添加禁用的滚动条以填补空白:
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>
我正是针对自己的灯箱实现来执行此操作。到目前为止似乎运作良好。
这就是我们所采用的解决方案。只需在打开叠加层时保存滚动位置,即可在用户尝试滚动页面时滚动回到保存的位置,并在关闭叠加层时关闭侦听器。
在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>
z-index
of 调整.overlay-shown
为大于固定标题。(我的代码在具有固定标头的网站上在生产环境中运行,并且可以正常工作。)
body
标签的滚动条。我昨天尝试了您的代码,并且在页面顶部有一个固定的标题。如果我通过body
标签处理滚动,则滚动条将位于固定标题下。
$("body")
我们在用$(window)
。z-index: -1
您可以使用visibility: hidden
或类似的方法,而不是将其隐藏在叠加层上。请参阅jsfiddle.net/8p2gfeha进行快速测试,以查看其是否有效。固定的标题不再出现在滚动条的顶部。我最终将尝试将这些更改纳入答案。
我喜欢坚持“溢出:隐藏”方法,只添加等于滚动条宽度的padding-right。
通过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;
}
显示叠加层时,将“ noscroll”类添加到html并将padding-right添加到正文:
$(html).addClass("noscroll");
$(body).css("paddingRight", getScrollbarWidth() + "px");
隐藏时,删除类和填充:
$(html).removeClass("noscroll");
$(body).css("paddingRight", 0);
noscroll样式就是这样:
.noscroll { overflow: hidden; }
请注意,如果您有任何位置固定的元素,则还需要在这些元素上添加填充。
<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>
现在,滚动到灯箱(及其上方body
)将不起作用,因为主体不超过屏幕高度的100%。
如果覆盖层下的页面可以在顶部“固定”,则在打开覆盖层时可以设置
.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));
我只是以这种方式提出了建议,因为您不需要更改任何滚动事件
通过保存滚动位置并在启用滚动功能后将其恢复,将阻止视口跳到顶部。
的CSS
.no-scroll{
position: fixed;
width:100%;
min-height:100vh;
top:0;
left:0;
overflow-y:scroll!important;
}
JS
var scrollTopPostion = 0;
function scroll_pause(){
scrollTopPostion = $(window).scrollTop();
$("body").addClass("no-scroll").css({"top":-1*scrollTopPostion+"px"});
}
function scroll_resume(){
$("body").removeClass("no-scroll").removeAttr("style");
$(window).scrollTop(scrollTopPostion);
}
现在您需要做的就是调用函数
$(document).on("click","#DISABLEelementID",function(){
scroll_pause();
});
$(document).on("click","#ENABLEelementID",function(){
scroll_resume();
});
您可以使用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>
然后仅将onscroll
事件应用于#global
。