我想创建一个 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/