如何在DraftJS只读模式下实现「显示全部/收起」功能?
实现DraftJS只读模式下内容折叠/展开功能的思路
嘿,这个需求其实很好落地,咱们一步步拆解来做就清晰了:
1. 先搞定状态开关
首先在你的React组件里加个状态,用来控制内容是展开还是收起,比如:
const [isExpanded, setIsExpanded] = useState(false);
初始设为false,也就是默认只显示前几行内容。
2. 编写内容截断逻辑
DraftJS的内容基于EditorState,咱们需要把完整内容转成截断后的版本。核心思路是:
- 用
convertToRaw把完整的EditorState转成原始数据结构 - 截取前N个block(默认每个block对应一行,你可以按需调整行数)
- 再用
convertFromRaw把截断后的原始数据转回EditorState
给你写个实用的工具函数示例:
import { convertToRaw, convertFromRaw, EditorState } from 'draft-js'; const getTruncatedEditorState = (fullEditorState, maxLines = 3) => { const rawContent = convertToRaw(fullEditorState.getCurrentContent()); // 只保留前maxLines个内容块 const truncatedBlocks = rawContent.blocks.slice(0, maxLines); // 如果内容被截断了,加个省略号提示(可选) if (rawContent.blocks.length > maxLines) { truncatedBlocks.push({ key: 'ellipsis-block', text: '...', type: 'unstyled', depth: 0, inlineStyleRanges: [], entityRanges: [], data: {} }); } return EditorState.createWithContent(convertFromRaw({ ...rawContent, blocks: truncatedBlocks })); };
3. 根据状态渲染对应内容
渲染时根据isExpanded的值,决定显示完整内容还是截断后的内容,同时加上切换链接:
const truncatedEditorState = getTruncatedEditorState(yourFullEditorState); return ( <div className="draft-readonly-container" style={{ position: 'relative' }}> <Editor editorState={isExpanded ? yourFullEditorState : truncatedEditorState} readOnly={true} // 这里放你原本的Editor配置项 /> {/* 只有内容超过设定行数时才显示切换链接 */} {yourFullEditorState.getCurrentContent().getBlockMap().size > 3 && ( <span className="toggle-link" onClick={() => setIsExpanded(!isExpanded)} style={{ cursor: 'pointer', color: '#007bff', marginTop: 8, display: 'inline-block' }} > {isExpanded ? '再次收起' : '显示全部'} </span> )} </div> );
4. 可选:添加视觉增强
为了让用户更直观感受到内容被截断,可以给容器加个渐变遮罩:
.draft-readonly-container::after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 40px; background: linear-gradient(to bottom, rgba(255,255,255,0), rgba(255,255,255,1)); display: none; } .draft-readonly-container.collapsed::after { display: block; }
记得在渲染容器时根据isExpanded动态添加collapsed类名就行。
小提醒
如果你的内容里有复杂的block(比如多级列表、引用块),可以调整截断逻辑——比如按实际渲染后的行数计算,但这种方式受样式影响较大,不如直接按block数量截断稳定。另外要确保readOnly属性始终设为true,避免用户误编辑。
内容的提问来源于stack exchange,提问作者acmoune
相关产品推荐
相关产品推荐

