admin管理员组文章数量:1420166
I have successfully implemented the show more/show less. My problem is that I want to achieve it based on the number of lines or height of the screen. I don't want it to be based on number of characters since it would look bad on certain screens. like kinda cut on larger screen while too long on small screens.
Pls check my codesandbox here CLICK HERE
<DescriptionText>
{isShowMore ? text.slice(0, 300) : text}
</DescriptionText>
{text && text.length > 300 && (
<ShowMoreText onClick={toggleReadMore}>
{isShowMore ? "Show more..." : "Show less"}
</ShowMoreText>
)}
I have successfully implemented the show more/show less. My problem is that I want to achieve it based on the number of lines or height of the screen. I don't want it to be based on number of characters since it would look bad on certain screens. like kinda cut on larger screen while too long on small screens.
Pls check my codesandbox here CLICK HERE
<DescriptionText>
{isShowMore ? text.slice(0, 300) : text}
</DescriptionText>
{text && text.length > 300 && (
<ShowMoreText onClick={toggleReadMore}>
{isShowMore ? "Show more..." : "Show less"}
</ShowMoreText>
)}
Share
Improve this question
edited Aug 1, 2021 at 7:51
Drew Reese
204k18 gold badges246 silver badges274 bronze badges
asked Jul 20, 2021 at 5:58
JosephJoseph
7,80532 gold badges105 silver badges228 bronze badges
2 Answers
Reset to default 4Since you are using styled-ponents
I've found a great utility package for it: polished.js
You would be looking for the ellipsis utility.
ellipsis
CSS to represent truncated text with an ellipsis. You can optionally pass a max-width and number of lines before truncating.
ellipsis(width: (string? | number?)?, lines: number): Styles
Example: Display up to 3 lines when show more, otherwise full text.
import { ellipsis } from 'polished';
...
const DescriptionText = styled.div`
font-size: 14px;
margin-top: 20px;
margin-bottom: 20px;
${({ showMore }) => showMore && ellipsis(undefined, 3)}
`;
...
const Description = () => {
const [isShowMore, setIsShowMore] = useState(true);
const toggleReadMore = () => setIsShowMore(show => !show);
return (
<MainContainer>
<TitleText>Description</TitleText>
<DescriptionText showMore={isShowMore}>{text}</DescriptionText>
<ShowMoreText onClick={toggleReadMore}>
{isShowMore ? "Show more..." : "Show less"}
</ShowMoreText>
</MainContainer>
);
};
You seem to have mentioned in another answer that you don't want to add any new dependencies, so here is the CSS that is applied via the ellipsis
utility. Though, I'd still remend adding polished
to your project if you can as it has many useful styling utilities I've found fairly invaluable.
import styled, { css } from "styled-ponents";
const DescriptionText = styled.div`
font-size: 14px;
margin-top: 20px;
margin-bottom: 20px;
${({ showMore }) =>
showMore &&
css`
display: -webkit-box;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
word-wrap: normal;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
`}
`;
To handle different screen sizes/responsiveness you can use media queries and specify a different number of lines you want to initially display.
How about window.innerHeight < minHeight
? This means you need to define minHeight
const text = `Lorem ipsum .....`; //
let _shouldTruncate = null;
const minHeight = 750;
const Description = () => {
const descTextEl = useRef(null);
const [isShowMore, setIsShowMore] = useState(true);
const toggleReadMore = () => {
setIsShowMore(!isShowMore);
};
const [txtVal, setTxtVal] = useState(""); //save value to state
//updates `txtVal` on change of `isShowMore`
useEffect(() => {
if (_shouldTruncate === null) {
_shouldTruncate = window.innerHeight < minHeight;
}
setTxtVal(_shouldTruncate && isShowMore ? text.slice(0, 300) : text);
}, [txtVal, isShowMore]);
return (
<MainContainer>
<TitleText>Description</TitleText>
<DescriptionText ref={descTextEl}>{txtVal}</DescriptionText>
{_shouldTruncate && (
<ShowMoreText onClick={toggleReadMore}>
{isShowMore ? "Show more..." : "Show less"}
</ShowMoreText>
)}
</MainContainer>
);
};
UPDATE:
Since you wanted to get the number of lines, you might need to calculate it using this logic from this answer:
function countLines() {
var el = document.getElementById('content');
var divHeight = el.offsetHeight
var lineHeight = parseInt(el.style.lineHeight);
//or use puted lineHeight:
//var lineHeight = document.defaultView.getComputedStyle(el, null).getPropertyValue("lineHeight");
var lines = divHeight / lineHeight;
alert("Lines: " + lines);
}
Update:
You need to import ReactDom
to calculate the style.
Code Sandbox using window.innerHeight
Code Sandbox based on number of lines
本文标签: javascriptShow more based on height in ReactStack Overflow
版权声明:本文标题:javascript - Show more based on height in React - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745308988a2652820.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论