如何检查 div 是否在反应功能组件中溢出
How to check if a div is overflowing in react functional component
我正在尝试查明 div 是否溢出文本,如果溢出则显示 show more
link。我找到了this Whosebug answer to check if a div is overflowing。根据这个答案,我需要实现一个可以访问相关元素样式的函数,并进行一些检查以查看它是否溢出。如何访问元素的样式。我尝试了两种方式
1.使用 ref
import React from "react";
import "./styles.css";
export default function App(props) {
const [showMore, setShowMore] = React.useState(false);
const onClick = () => {
setShowMore(!showMore);
};
const checkOverflow = () => {
const el = ref.current;
const curOverflow = el.style.overflow;
if ( !curOverflow || curOverflow === "visible" )
el.style.overflow = "hidden";
const isOverflowing = el.clientWidth < el.scrollWidth
|| el.clientHeight < el.scrollHeight;
el.style.overflow = curOverflow;
return isOverflowing;
};
const ref = React.createRef();
return (
<>
<div ref={ref} className={showMore ? "container-nowrap" : "container"}>
{props.text}
</div>
{(checkOverflow()) && <span className="link" onClick={onClick}>
{showMore ? "show less" : "show more"}
</span>}
</>
)
}
2。使用前向参考
子组件
export const App = React.forwardRef((props, ref) => {
const [showMore, setShowMore] = React.useState(false);
const onClick = () => {
setShowMore(!showMore);
};
const checkOverflow = () => {
const el = ref.current;
const curOverflow = el.style.overflow;
if (!curOverflow || curOverflow === "visible") el.style.overflow = "hidden";
const isOverflowing =
el.clientWidth < el.scrollWidth || el.clientHeight < el.scrollHeight;
el.style.overflow = curOverflow;
return isOverflowing;
};
return (
<>
<div ref={ref} className={showMore ? "container-nowrap" : "container"}>
{props.text}
</div>
{checkOverflow() && (
<span className="link" onClick={onClick}>
{showMore ? "show less" : "show more"}
</span>
)}
</>
);
});
父组件
import React from "react";
import ReactDOM from "react-dom";
import { App } from "./App";
const rootElement = document.getElementById("root");
const ref = React.createRef();
ReactDOM.render(
<React.StrictMode>
<App
ref={ref}
text="Start editing to see some magic happen! Click show more to expand and show less to collapse the text"
/>
</React.StrictMode>,
rootElement
);
但是我在两种方法中都遇到了以下错误 - Cannot read property 'style' of null
。
我究竟做错了什么?我怎样才能达到我想要的?
正如 Jamie Dixon 在评论中建议的那样,我使用 useLayoutEffect
钩子将 showLink
设置为 true。这是代码
组件
import React from "react";
import "./styles.css";
export default function App(props) {
const ref = React.createRef();
const [showMore, setShowMore] = React.useState(false);
const [showLink, setShowLink] = React.useState(false);
React.useLayoutEffect(() => {
if (ref.current.clientWidth < ref.current.scrollWidth) {
setShowLink(true);
}
}, [ref]);
const onClickMore = () => {
setShowMore(!showMore);
};
return (
<div>
<div ref={ref} className={showMore ? "" : "container"}>
{props.text}
</div>
{showLink && (
<span className="link more" onClick={onClickMore}>
{showMore ? "show less" : "show more"}
</span>
)}
</div>
);
}
CSS
.container {
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 200px;
}
.link {
text-decoration: underline;
cursor: pointer;
color: #0d6aa8;
}
我们可以创建一个自定义挂钩来了解我们是否有溢出。
import * as React from 'react';
const useIsOverflow = (ref, isVerticalOverflow, callback) => {
const [isOverflow, setIsOverflow] = React.useState(undefined);
React.useLayoutEffect(() => {
const { current } = ref;
const { clientWidth, scrollWidth, clientHeight, scrollHeight } = current;
const trigger = () => {
const hasOverflow = isVerticalOverflow ? scrollHeight > clientHeight : scrollWidth > clientWidth;
setIsOverflow(hasOverflow);
if (callback) callback(hasOverflow);
};
if (current) {
trigger();
}
}, [callback, ref, isVerticalOverflow]);
return isOverflow;
};
export default useIsOverflow;
然后只需签入您的组件
import * as React from 'react';
import { useIsOverflow } from './useIsOverflow';
const App = () => {
const ref = React.useRef();
const isOverflow = useIsOverflow(ref);
console.log(isOverflow);
// true
return (
<div style={{ overflow: 'auto', height: '100px' }} ref={ref}>
<div style={{ height: '200px' }}>Hello React</div>
</div>
);
};
感谢 Robin Wieruch 的精彩文章
https://www.robinwieruch.de/react-custom-hook-check-if-overflow/
我正在尝试查明 div 是否溢出文本,如果溢出则显示 show more
link。我找到了this Whosebug answer to check if a div is overflowing。根据这个答案,我需要实现一个可以访问相关元素样式的函数,并进行一些检查以查看它是否溢出。如何访问元素的样式。我尝试了两种方式
1.使用 ref
import React from "react";
import "./styles.css";
export default function App(props) {
const [showMore, setShowMore] = React.useState(false);
const onClick = () => {
setShowMore(!showMore);
};
const checkOverflow = () => {
const el = ref.current;
const curOverflow = el.style.overflow;
if ( !curOverflow || curOverflow === "visible" )
el.style.overflow = "hidden";
const isOverflowing = el.clientWidth < el.scrollWidth
|| el.clientHeight < el.scrollHeight;
el.style.overflow = curOverflow;
return isOverflowing;
};
const ref = React.createRef();
return (
<>
<div ref={ref} className={showMore ? "container-nowrap" : "container"}>
{props.text}
</div>
{(checkOverflow()) && <span className="link" onClick={onClick}>
{showMore ? "show less" : "show more"}
</span>}
</>
)
}
2。使用前向参考
子组件
export const App = React.forwardRef((props, ref) => {
const [showMore, setShowMore] = React.useState(false);
const onClick = () => {
setShowMore(!showMore);
};
const checkOverflow = () => {
const el = ref.current;
const curOverflow = el.style.overflow;
if (!curOverflow || curOverflow === "visible") el.style.overflow = "hidden";
const isOverflowing =
el.clientWidth < el.scrollWidth || el.clientHeight < el.scrollHeight;
el.style.overflow = curOverflow;
return isOverflowing;
};
return (
<>
<div ref={ref} className={showMore ? "container-nowrap" : "container"}>
{props.text}
</div>
{checkOverflow() && (
<span className="link" onClick={onClick}>
{showMore ? "show less" : "show more"}
</span>
)}
</>
);
});
父组件
import React from "react";
import ReactDOM from "react-dom";
import { App } from "./App";
const rootElement = document.getElementById("root");
const ref = React.createRef();
ReactDOM.render(
<React.StrictMode>
<App
ref={ref}
text="Start editing to see some magic happen! Click show more to expand and show less to collapse the text"
/>
</React.StrictMode>,
rootElement
);
但是我在两种方法中都遇到了以下错误 - Cannot read property 'style' of null
。
我究竟做错了什么?我怎样才能达到我想要的?
正如 Jamie Dixon 在评论中建议的那样,我使用 useLayoutEffect
钩子将 showLink
设置为 true。这是代码
组件
import React from "react";
import "./styles.css";
export default function App(props) {
const ref = React.createRef();
const [showMore, setShowMore] = React.useState(false);
const [showLink, setShowLink] = React.useState(false);
React.useLayoutEffect(() => {
if (ref.current.clientWidth < ref.current.scrollWidth) {
setShowLink(true);
}
}, [ref]);
const onClickMore = () => {
setShowMore(!showMore);
};
return (
<div>
<div ref={ref} className={showMore ? "" : "container"}>
{props.text}
</div>
{showLink && (
<span className="link more" onClick={onClickMore}>
{showMore ? "show less" : "show more"}
</span>
)}
</div>
);
}
CSS
.container {
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 200px;
}
.link {
text-decoration: underline;
cursor: pointer;
color: #0d6aa8;
}
我们可以创建一个自定义挂钩来了解我们是否有溢出。
import * as React from 'react';
const useIsOverflow = (ref, isVerticalOverflow, callback) => {
const [isOverflow, setIsOverflow] = React.useState(undefined);
React.useLayoutEffect(() => {
const { current } = ref;
const { clientWidth, scrollWidth, clientHeight, scrollHeight } = current;
const trigger = () => {
const hasOverflow = isVerticalOverflow ? scrollHeight > clientHeight : scrollWidth > clientWidth;
setIsOverflow(hasOverflow);
if (callback) callback(hasOverflow);
};
if (current) {
trigger();
}
}, [callback, ref, isVerticalOverflow]);
return isOverflow;
};
export default useIsOverflow;
然后只需签入您的组件
import * as React from 'react';
import { useIsOverflow } from './useIsOverflow';
const App = () => {
const ref = React.useRef();
const isOverflow = useIsOverflow(ref);
console.log(isOverflow);
// true
return (
<div style={{ overflow: 'auto', height: '100px' }} ref={ref}>
<div style={{ height: '200px' }}>Hello React</div>
</div>
);
};
感谢 Robin Wieruch 的精彩文章 https://www.robinwieruch.de/react-custom-hook-check-if-overflow/