我一直在寻找一种“灯箱”类型的解决方案,可以实现此功能,但目前还没有找到(如果您知道任何信息,请提供建议)。
我试图重新创建的行为就像您在Pinterest上点击图像时看到的那样。该覆盖层是可滚动的(就像页面上一页上移一样整个覆盖层向上移动),但是覆盖层后面的主体是固定的。
我尝试只使用CSS来创建它(例如,在整个页面和带有overflow:hidden
的body上放置一个
如何保持主体/页面不滚动但在全屏容器内滚动?
我一直在寻找一种“灯箱”类型的解决方案,可以实现此功能,但目前还没有找到(如果您知道任何信息,请提供建议)。
我试图重新创建的行为就像您在Pinterest上点击图像时看到的那样。该覆盖层是可滚动的(就像页面上一页上移一样整个覆盖层向上移动),但是覆盖层后面的主体是固定的。
我尝试只使用CSS来创建它(例如,在整个页面和带有overflow:hidden
的body上放置一个
如何保持主体/页面不滚动但在全屏容器内滚动?
<body>
<input>
打开虚拟键盘将把所有未来的滚动转移到<body>
我无法解决第一个问题,但想阐明第二个问题。令人困惑的是,Bootstrap曾经记录了这个键盘问题,但他们声称已经修复了此问题,并引用http://output.jsbin.com/cacido/quiet作为修复示例。
事实上,在我的测试中,该示例在iOS上运行良好。然而,将其升级到最新版本的Bootstrap(v4)会使其崩溃。
为了找出它们之间的差异,我将测试案例简化,不再依赖于Bootstrap,http://codepen.io/WestonThayer/pen/bgZxBG。
决定因素很奇怪。避免键盘问题似乎要求在包含模式的根<div>
上未设置background-color
,并且模式的内容必须嵌套在另一个<div>
中,该<div>
可以设置background-color
。
要进行测试,请取消Codepen示例中下面的行的注释:
.modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2;
display: none;
overflow: hidden;
-webkit-overflow-scrolling: touch;
/* UNCOMMENT TO BREAK */
/* background-color: white; */
}
我发现这个问题是为了解决我在iPad和iPhone上遇到的问题而提出的,当我显示固定的弹出图像时,页面会滚动。
一些答案很好,但是没有一个解决我的问题。我找到了Christoffer Pettersson的以下博客文章。他提出的解决方案帮助了我在iOS设备上遇到的问题,并解决了我的滚动背景问题。
正如建议的那样,我包括了博客文章的主要要点,以防链接过期。
"为了禁用用户在“菜单打开”时可以滚动背景页面,可以通过应用一些JavaScript和CSS类来控制哪些元素应该允许滚动或不允许滚动。
根据这个Stackoverflow答案,您可以控制带有disable-scrolling的元素,在触摸移动事件触发时不执行其默认滚动操作。"
document.ontouchmove = function ( event ) {
var isTouchMoveAllowed = true, target = event.target;
while ( target !== null ) {
if ( target.classList && target.classList.contains( 'disable-scrolling' ) ) {
isTouchMoveAllowed = false;
break;
}
target = target.parentNode;
}
if ( !isTouchMoveAllowed ) {
event.preventDefault();
}
};
然后将disable-scrolling类放在页面div上:
<div class="page disable-scrolling">
101vh
最小高度透明div。然后将-webkit-overflow-scrolling:touch; overflow-y: auto;
添加到包装器中。这会欺骗移动safari认为覆盖层是可滚动的,从而拦截来自body的触摸事件。-webkit-overflow-scrolling:touch;
以拦截触摸事件即可。 - Mati为body标签添加简单的内联样式:
<body style="position: sticky; overflow: hidden;">
touch-action: none;
。const app = document.getElementById('app');
const overlay = document.getElementById('overlay');
let body = '';
for (let index = 0; index < 500; index++) {
body += index + '<br />';
}
app.innerHTML = body;
app.scrollTop = 200;
overlay.innerHTML = body;
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
#app {
background: #f00;
position: absolute;
height: 100%;
width: 100%;
overflow-y: scroll;
line-height: 20px;
}
#overlay {
background: rgba(0,0,0,.5);
position: fixed;
top: 0;
left: 0;
right: 0;
height: 100%;
padding: 0 0 0 100px;
overflow: scroll;
}
<div id='app'></div>
<div id='overlay'></div>
在 Stack Overflow 上下文中,此示例无法正常工作。您需要在独立页面中重新创建它。
如果您想禁用 #app
容器的滚动,请添加 touch-action: none;
。
<body>
<div class="page">Page content here</div>
<div class="overlay"></div>
</body>
$(".page").on("touchmove", function(event) {
event.preventDefault()
});
$(".page").off("touchmove");
我想补充之前的回答,因为我尝试这样做时,一些布局在将body设置为position:fixed后立即破裂。为了避免这种情况,我还必须将body的高度设置为100%:
function onMouseOverOverlay(over){
document.getElementsByTagName("body")[0].style.overflowY = (over?"hidden":"scroll");
document.getElementsByTagName("html")[0].style.position = (over?"fixed":"static");
document.getElementsByTagName("html")[0].style.height = (over?"100%":"auto");
}
试一下这个
var mywindow = $('body'), navbarCollap = $('.navbar-collapse');
navbarCollap.on('show.bs.collapse', function(x) {
mywindow.css({visibility: 'hidden'});
$('body').attr("scroll","no").attr("style", "overflow: hidden");
});
navbarCollap.on('hide.bs.collapse', function(x) {
mywindow.css({visibility: 'visible'});
$('body').attr("scroll","yes").attr("style", "");
});
import {useEffect, useRef} from "react";
export default function PopoverMenu({className, handleClose, children}) {
const selfRef = useRef(undefined);
useEffect(() => {
const isPopoverOpenned = selfRef.current?.style.display !== "none";
const focusedElement = document?.activeElement;
const scrollPosition = {x: window.scrollX, y: window.scrollY};
if (isPopoverOpenned) {
preventDocBodyScrolling();
} else {
restoreDocBodyScrolling();
}
function preventDocBodyScrolling() {
const width = document.body.clientWidth;
const hasVerticalScrollBar = (window.innerWidth > document.documentElement.clientWidth);
document.body.style.overflowX = "hidden";
document.body.style.overflowY = hasVerticalScrollBar ? "scroll" : "";
document.body.style.width = `${width}px`;
document.body.style.position = "fixed";
}
function restoreDocBodyScrolling() {
document.body.style.overflowX = "";
document.body.style.overflowY = "";
document.body.style.width = "";
document.body.style.position = "";
focusedElement?.focus();
window.scrollTo(scrollPosition.x, scrollPosition.y);
}
return () => {
restoreDocBodyScrolling(); // cleanup on unmount
};
}, []);
return (
<>
<div
className="backdrop"
onClick={() => handleClose && handleClose()}
/>
<div
className={`pop-over-menu${className ? (` ${className}`) : ""}`}
ref={selfRef}
>
<button
className="pop-over-menu--close-button" type="button"
onClick={() => handleClose && handleClose()}
>
X
</button>
{children}
</div>
</>
);
}
最初发布在与此相关的Stackoverflow问题上:https://dev59.com/JGkw5IYBdhLWcg3w9vJ-#69016517