我想让我的身体在使用鼠标滚轮时停止滚动,而我的网站上的Modal(来自http://twitter.github.com/bootstrap)是打开的。
当模式被打开时,我试图调用下面的javascript片段,但没有成功
$(window).scroll(function() { return false; });
AND
$(window).live('scroll', function() { return false; });
请注意,我们的网站放弃了对IE6的支持,IE7+需要兼容。
我有一个边栏,是由复选框黑客生成的。
但主要思想是保存文档scrollTop,而不是在滚动窗口期间更改它。
我只是不喜欢页面跳转时,身体变成'溢出:隐藏'。
window.addEventListener('load', function() {
let prevScrollTop = 0;
let isSidebarVisible = false;
document.getElementById('f-overlay-chkbx').addEventListener('change', (event) => {
prevScrollTop = window.pageYOffset || document.documentElement.scrollTop;
isSidebarVisible = event.target.checked;
window.addEventListener('scroll', (event) => {
if (isSidebarVisible) {
window.scrollTo(0, prevScrollTop);
}
});
})
});
Bootstrap的模态在模态对话框显示时自动将类modal-open添加到主体,并在对话框隐藏时将其删除。因此,您可以在CSS中添加以下内容:
body.modal-open {
overflow: hidden;
}
你可能会说上面的代码属于Bootstrap CSS代码库,但这是一个简单的修复,可以将它添加到你的网站。
2013年2月8日更新
这在Twitter Bootstrap v. 2.3.0中已经停止工作——他们不再向主体添加modal-open类。
一个变通的方法是在模态即将显示时将类添加到主体中,并在模态关闭时将其删除:
$("#myModal").on("show", function () {
$("body").addClass("modal-open");
}).on("hidden", function () {
$("body").removeClass("modal-open")
});
2013年3月11日更新
看起来modal-open类将在Bootstrap 3.0中返回,显式地用于防止滚动:
在body上重新引入。modal-open(这样我们就可以把滚动移到这里)
看这个:https://github.com/twitter/bootstrap/pull/6342 -看Modal部分。
试试下面的代码:
$('.entry_details').dialog({
width:800,
height:500,
draggable: true,
title: entry.short_description,
closeText: "Zamknij",
open: function(){
// blokowanie scrolla dla body
var body_scroll = $(window).scrollTop();
$(window).on('scroll', function(){
$(document).scrollTop(body_scroll);
});
},
close: function(){
$(window).off('scroll');
}
});
基于此提琴:http://jsfiddle.net/dh834zgw/1/
下面的代码片段(使用jquery)将禁用窗口滚动:
var curScrollTop = $(window).scrollTop();
$('html').toggleClass('noscroll').css('top', '-' + curScrollTop + 'px');
在你的css中:
html.noscroll{
position: fixed;
width: 100%;
top:0;
left: 0;
height: 100%;
overflow-y: scroll !important;
z-index: 10;
}
现在,当你删除模态时,不要忘记删除html标签上的noscroll类:
$('html').toggleClass('noscroll');
我读的大多数答案都是关于React的。
我的React功能组件的最佳解决方案是使用@arcticmatt最初提供的解决方案
我在下面的代码示例中包含了一些在其他答案中提到的改进(注意useEffect定义):
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>
</>
);
}