You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:33:08