这是一个针对NextJS、React、Typescript和Tailwind的解决方案,其中包括一个“阅读更多...”按钮,当文本被压缩时会显示。
代码前的描述:
这是一个React组件,它作为prop获取post(可以是任何其他内容)。 post包含应该显示的内容,带有4行夹紧,直到用户点击“阅读更多...”。
内容引用(使用useRef钩子)保存了对应该显示内容的内容div的引用。
第一个useState钩子保存状态isClamped:如果内容被压缩,则为true,否则为false。
第二个useState保存状态isExpanded:如果用户已单击“阅读更多...”,则为true,否则为false。
然后,useEffect钩子仅在挂载时调用,因为空数组设置,添加事件侦听器以便于窗口大小调整(可能会影响内容行数)。当窗口大小调整时,将contentRef(具有内容的div)scrollHeight与clientHeight进行比较,就像上面的其他答案一样。如果scrollHeight较大,则isClamped将设置为true,否则为false。
现在,在包含内容的div中,如果isExpanded为false(用户还没有单击“阅读更多...”),则className将设置为“line-clamp-4”(将限制内容为4行),否则className将设置为“line-clamp-none”(无夹紧)。
最后,在包含“阅读更多...”文本的div中,如果isClamped为true(因此文本被夹紧),则将显示该文本。
import {useState, useRef, useEffect}
interface PostItemProps {
post: Post
}
export default function PostItem({post}: PostItemProps){
const contentRef = useRef<HTMLDivElement>(null)
const [isClamped, setClamped] = useState(false)
const [isExpanded, setExpanded] = useState(false)
useEffect(() => {
function handleResize() {
if (contentRef && contentRef.current) {
setClamped(
contentRef.current.scrollHeight > contentRef.current.clientHeight
)
}
}
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
return (
<div>
<div ref={contentRef} className={`${ !exapnded ? 'line-clamp-4' : 'line-clamp-none' }> {post.content} </div>
</div>
{isClamped && (
<div className="flex justify-end">
<button
className="font-bold text-title"
onClick={() => setExpanded(true)}
>
See More...
</button>
</div>
)}
</div>
)
}