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

如何为Draft.js中大量独立字符批量应用自定义行内样式

Draft.js自定义语法高亮批量样式设置方案

你要实现的单字符粒度自定义样式完全可以通过直接操作ContentBlock的characterList实现,不需要逐字符调用RichUtils.toggleInlineStyle,性能足以支撑IDE级别的语法高亮需求。

核心原理

Draft.js的每个ContentBlock都维护了一个characterList属性(就是你在文档里看到的样式数组),每个位置对应一个Immutable.OrderedSet,存储当前字符的所有inline样式。你只需要按自己的语法高亮规则批量生成这个List,替换原有属性即可。

注:Draft.js依赖Immutable.js的OrderedSet实现样式存储,相关API可以直接查阅Immutable.js官方定义,Draft文档没有单独说明。

实现步骤

  1. 首先配置自定义样式映射,传入Editor组件的customStyleMap属性:
const customStyleMap = {
  red: { color: '#ff0000' },
  keyword: { color: '#7928ca', fontWeight: 'bold' },
  string: { color: '#008000' },
  // 其他你需要的自定义样式
}
  1. 替换你现有的onChange逻辑,批量处理样式:
import { OrderedSet } from 'immutable';
import { EditorState, ContentState, CharacterMetadata } from 'draft-js';

const onChange = (newEditorState) => {
  const contentState = newEditorState.getCurrentContent();
  const currentSelection = newEditorState.getSelection();
  
  // 遍历所有block,批量更新样式
  const newBlockMap = contentState.getBlockMap().map(block => {
    const blockText = block.getText();
    // 这里替换成你自己的语法高亮逻辑,返回每个字符对应的样式数组
    // 示例:假设第0-2个字符要加red样式,第3-5个加keyword样式
    const charMetadataList = [];
    for (let i = 0; i < blockText.length; i++) {
      let styles = OrderedSet();
      // 你的高亮判断逻辑
      if (i < 3) {
        styles = styles.add('red');
      } else if (i < 6) {
        styles = styles.add('keyword');
      }
      charMetadataList.push(CharacterMetadata.create({ style: styles }));
    }
    // 替换block的characterList
    return block.set('characterList', Immutable.List(charMetadataList));
  });
  
  // 生成新的contentState和editorState,保留原有光标位置
  const newContentState = ContentState.createFromBlockArray(newBlockMap.toArray());
  const finalEditorState = EditorState.push(
    newEditorState,
    newContentState,
    'change-inline-style'
  );
  const editorStateWithSelection = EditorState.forceSelection(finalEditorState, currentSelection);
  
  setEditorState(editorStateWithSelection);
}

性能优化建议

  • 语法分词可以做防抖处理,只有用户停止输入100-200ms后再重新计算样式,避免输入卡顿
  • 缓存已经分词过的block,只有block文本发生变化时才重新计算样式,不需要每次onChange都全量遍历

内容的提问来源于stack exchange,提问作者dontfknow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 21:24:03