javascript - Visa 'Läs mer' på samma rad som avklippt text efter 'x' rader
Jag försöker lägga till åtgärden Läs mer på samma rad som den avklippta texten efter 'x' rader. Just nu visas den under den avklippta texten.
<p style={{ overflow: 'hidden', display: '-webkit-box',
-webkit-line-clamp: 4, line-clamp: 4, -webkit-box-orient: 'vertical'
}}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
</p>
<Button>Read more</Button>
Jag kan hantera funktionen där texten växlas genom att ändra overflow-egenskapen till visible/hidden. Jag försöker bara styla det på ett sätt där Läs mer alltid är på sista raden i stället för ellipsis.
Detta klipper för närvarande av vid 4 rader vilket är korrekt, men vill ersätta ellipsen med knappen Läs mer.
All hjälp uppskattas
Svar #1
Här är ett exempel:
import { useState, useRef, useEffect } from 'react';
const ClampTextWithReadMore = ({ text, maxLines }) => {
const [isClamped, setIsClamped] = useState(false);
const textRef = useRef(null);
useEffect(() => {
if (textRef.current) {
const computedStyle = window.getComputedStyle(textRef.current);
const lineHeight = parseInt(computedStyle.lineHeight);
const maxHeight = maxLines * lineHeight;
if (textRef.current.scrollHeight > maxHeight) {
setIsClamped(true);
}
}
}, [text, maxLines]);
const toggleClamp = () => {
setIsClamped(!isClamped);
};
return (
<div style={{ position: 'relative' }}>
<p
ref={textRef}
style={{
overflow: isClamped ? 'hidden' : 'visible',
display: '-webkit-box',
WebkitLineClamp: maxLines,
WebkitBoxOrient: 'vertical',
maxHeight: isClamped ? `${maxLines * 1.2}em` : 'none', // Adjust as needed
}}
>
{text}
</p>
{isClamped && (
<button style={{ position: 'absolute', bottom: 0, right: 0 }} onClick={toggleClamp}>
Read more
</button>
)}
</div>
);
};
// Usage
<ClampTextWithReadMore text={/* Your text here */} maxLines={4} />;
Denna kodsnutt använder useRef för att komma åt DOM-elementet som innehåller texten och beräknar om texten är begränsad baserat på maximal höjd. Om texten är begränsad renderas villkorligt knappen "Läs mer" som är placerad längst ner till höger i det begränsade området. Att klicka på knappen växlar det begränsade tillståndet.
Svar #2
Placera knappen inuti paragraf-taggen så att den blir en del av textflödet. Sedan behöver du använda lite CSS för att korrekt positionera knappen under trunkering.
<div style={{ position: 'relative' }}>
<p style={{ overflow: 'hidden', display: '-webkit-box',
-webkit-line-clamp: 4, line-clamp: 4,
-webkit-box-orient: 'vertical', marginBottom: '0'
}}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
<span style={{ position: 'absolute', right: 0, bottom: 0 }}>
<Button>Read more</Button>
</span>
</p>
</div>
Skapa en anpassad funktion:
import React, { useState, useRef, useEffect } from 'react';
const EllipsisText = ({ children, maxLine, lineHeight }) => {
const textRef = useRef();
const [readMore, setReadMore] = useState(false);
const [text, setText] = useState(children);
const maxTextHeight = maxLine * lineHeight;
useEffect(() => {
if (textRef.current) {
if (textRef.current.scrollHeight > textRef.current.offsetHeight) {
setReadMore(true);
let trimLength = children.length * (maxTextHeight / textRef.current.scrollHeight);
setText(children.substring(0, trimLength - 3) + '...');
}
}
}, [children, maxTextHeight]);
return (
<div style={{ position: 'relative', lineHeight: `${lineHeight}px` }}>
<p ref={textRef} style={{ maxHeight: maxTextHeight, overflow: 'hidden' }}>
{text}
</p>
{readMore && (
<button style={{ position: 'absolute', right: 0, bottom: 0 }} onClick={() => setReadMore(false)}>
Read more
</button>
)}
</div>
);
};
const App = () => {
const text = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`;
return (
<div>
<EllipsisText maxLine={4} lineHeight={16}>
{text}
</EllipsisText>
</div>
);
};
export default App;
