我一直在寻找一个“灯箱”类型的解决方案,允许这一点,但还没有找到一个(请建议,如果你知道任何)。

我试图重现的行为就像你在Pinterest上点击图片时看到的一样。覆盖层是可滚动的(整个覆盖层向上移动,就像一页在一页的顶部),但覆盖层后面的主体是固定的。

我试图用CSS创建这个(即一个div覆盖在整个页面和身体溢出:隐藏),但它不阻止div是可滚动的。

如何保持主体/页面从滚动,但保持滚动在全屏容器内?


当前回答

要防止的行为称为滚动链接。要禁用它,请设置

overscroll-behavior: contain;

在你的CSS覆盖。

其他回答

如果有人正在寻找React函数组件的解决方案,你可以把它放在模态组件中:

 useEffect(() => {
    document.body.style.overflowY = 'hidden';
    return () =>{
      document.body.style.overflowY = 'auto';
    }
  }, [])

使用以下HTML:

<body>
  <div class="page">Page content here</div>
  <div class="overlay"></div>
</body>

然后用JavaScript拦截并停止滚动:

$(".page").on("touchmove", function(event) {
  event.preventDefault()
});

然后让事情恢复正常:

$(“.page”).off(“touchmove”);

如果你想在ios上防止过度滚动,你可以在你的.noscroll类中添加位置固定

body.noscroll{
    position:fixed;
    overflow:hidden;
}

要防止的行为称为滚动链接。要禁用它,请设置

overscroll-behavior: contain;

在你的CSS覆盖。

React功能组件的一个解决方案是使用useEffect钩子。

下面是下面的代码示例(请注意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>
    </>
  );
}

最初发表于另一个相关的Stackoverflow问题:https://stackoverflow.com/a/69016517/14131330