Next.js项目实现文本溢出折叠展开(指定行数不截断)
Next.js实现指定行数文本折叠/展开功能
实现思路
核心是通过CSS实现指定行数的文本自然折叠,再结合React状态控制展开/收起,同时自定义“Read more”交互按钮,避免生硬截断文本内容。
可复用组件实现
创建TextCollapse.tsx客户端组件(需使用React状态):
'use client'; import { useState, useRef, useEffect } from 'react'; interface TextCollapseProps { text: string; maxLines: number; readMoreText?: string; readLessText?: string; } const TextCollapse = ({ text, maxLines, readMoreText = 'Read more', readLessText = 'Read less', }: TextCollapseProps) => { const [isExpanded, setIsExpanded] = useState(false); const textRef = useRef<HTMLDivElement>(null); const [needsTruncation, setNeedsTruncation] = useState(false); useEffect(() => { const checkIfTruncated = () => { if (!textRef.current) return; // 对比容器高度和内容滚动高度,判断是否需要折叠 setNeedsTruncation(textRef.current.scrollHeight > textRef.current.clientHeight); }; checkIfTruncated(); // 监听窗口 resize,确保响应式场景下判断准确 window.addEventListener('resize', checkIfTruncated); return () => window.removeEventListener('resize', checkIfTruncated); }, [text]); // 如果文本不需要折叠,直接显示全部内容 if (!needsTruncation) { return <div>{text}</div>; } return ( <div className="relative"> <div ref={textRef} className={`transition-all duration-300 ${ isExpanded ? 'line-clamp-none' : `line-clamp-${maxLines}` }`} > {text} </div> <button onClick={() => setIsExpanded(!isExpanded)} className="absolute bottom-0 right-0 bg-white px-2 text-blue-600 hover:text-blue-800 focus:outline-none" > {isExpanded ? readLessText : readMoreText} </button> </div> ); }; export default TextCollapse;
样式适配
若未使用Tailwind CSS,可自定义CSS实现line-clamp效果:
/* 通用截断基础样式 */ .line-clamp { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; } /* 指定行数的截断类(示例为3行) */ .line-clamp-3 { -webkit-line-clamp: 3; } /* 展开时的样式 */ .line-clamp-none { display: block; -webkit-line-clamp: unset; }
组件使用示例
在页面或其他组件中引入使用:
import TextCollapse from '@/components/TextCollapse'; export default function ArticlePage() { const articleContent = `这里是需要折叠的长文本内容,会被自动截断到指定行数,点击Read more按钮可以展开全部内容,点击Read less又会折叠回去。整个过程不会生硬截断文本,而是完整保留行内内容,完全符合你的需求。`; return ( <div className="p-6 max-w-2xl mx-auto"> <h2 className="text-xl font-bold mb-3">文章标题</h2> <TextCollapse text={articleContent} maxLines={3} /> </div> ); }
核心要点
- 通过
scrollHeight与clientHeight的对比,精准判断文本是否需要折叠,避免按钮多余显示。 - 利用CSS的
-webkit-line-clamp实现指定行数的自然折叠,保证文本不会被生硬截断。 - 用React状态控制展开/收起状态,配合过渡动画提升交互流畅度。
内容的提问来源于stack exchange,提问作者Unnikrishnan KJ
相关产品推荐
相关产品推荐

