javascript - 如何检测嵌套 div 中的溢出(React)?

标签 javascript reactjs typescript styled-components

我想创建一个 div,它在 div 底部显示模糊(当存在溢出时)。问题是 div 包含 props.children,其中还包含其他组件/html 标签。

我尝试使用 ref (React.useRef),但 ref 甚至在子项渲染之前就已设置。我尝试将 useEffect 与 ref 一起使用,但当我使用例如 element.current.scrollbarHeight 时,我仍然得到 0。

如何检查渲染的 div(带有子元素)是否溢出? (我使用的是功能组件)

<div> {props.children} </div> 

为了生成模糊,我使用样式组件。

最佳答案

如果没有每个子项提供专门的回调,就不可能知道任意子项是否已完全渲染。因此,最好观察元素的大小变化。

我们可以使用ResizeObserver这对我们有利。

如果我们创建一对嵌套的 div:

<div class="fixed_size_overflow_auto">
    <div>
        {children}
    </div>
</div>

使外部 div 具有固定尺寸,我们可以监听内部 div 的大小调整。当我们检测到这些调整大小时,我们可以通过将其 offsetHeight 与其 scrollHeight 进行比较来计算外部 div 是否溢出。

这是一个想法,封装在一个可以使用 styled-components 进行样式设置的组件中:

const DetectContentResizeElement: FC<{
  className?: string;
  onContentResized?: (v: { hasOverflow: boolean }) => void;
}> = ({ children, onContentResized, className }) => {

  const contentRef = useRef<HTMLDivElement>(null);
  const outerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!contentRef.current || !outerRef.current) {
      return;
    }

    const obs = new ResizeObserver(() => {
      const hasOverflow =
        (outerRef.current?.offsetHeight ?? 0) <
        (contentRef.current?.offsetHeight ?? 0);
      onContentResized?.({ hasOverflow });
    });

    obs.observe(contentRef.current);
    return () => obs.disconnect();
  }, [onContentResized]);

  return (
    <div className={className} ref={outerRef}>
      <div ref={contentRef}>{children}</div>
    </div>
  );
};

您可以通过使用样式组件对其进行“子类化”来修复此组件的大小:

const FixedHeight = styled(DetectContentResizeElement)`
  height: 200px;
  width: 200px;
  border: solid 1px black;
  overflow: auto;
`;

现在您可以使用此容器并获取通知您何时溢出的事件:

  <FixedHeight
    onContentResized={({ hasOverflow }) =>
      console.log(`resized. hasOverflow: ${hasOverflow}`)
    }
  >
    <SomeChildElement />
  </FixedHeight>

在此 codesandbox project 中查看实际效果(使用 resize-observer-polyfill ponyfill 以获得最佳兼容性)

关于javascript - 如何检测嵌套 div 中的溢出(React)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65883719/

相关文章:

javascript - jQuery getScript() 与 document.createElement ('script' )

javascript - Bing map 在加载其 javascript 文件后未定义

javascript - 在 React Native 中将线放在图标下方

reactjs - 如何在reactjs中更新 map 函数中的状态

typescript - 奇怪的 typescript 错误 : Imports dependency not top level module

javascript - JQuery - 在数组中的项目(也是div)内查找子div

javascript - 使用 D3 设置 div 宽度

arrays - 如何在 React 中每次点击时过滤数组并更新状态

node.js - 如何用 `tsc` 和 `npm install` 解决鸡/蛋情况?

node.js - 更新到 webpack 5 后出现运行时错误。TypeError : Cannot read properties of undefined (reading 'default' )