关于draft富文本编辑框实现在指定位置插入链接的功能

964 阅读1分钟

开发需要用富文本编辑器实现一个插入链接的功能,但是google baidu了很多都没有找到好的解决办法,在解决后于是记录一下。

draft是一个facebook开发的以react为基础的富文本编辑器。github.com/facebook/dr…

因为一开始只是嗯啃draft文档,简单知道了draft生成的内容是一行一行的内容块,并且通过划定内容块中的文本来实现与entity的绑定,(修改内容块的样式也是这个策略)所以一开始我的实现这样的。

  const newBlock = new ContentBlock({
      key: newBlockKey,
      type: 'header-four',
      text: linkText,
      characterList: new List(Repeat(CharacterMetadata.create(), linkText.length)),
    });
    const newBlockMap = blocksBefore.concat(
      [[currentBlockKey, currentBlock], [newBlockKey, newBlock]],
      blocksAfter
    ).toOrderedMap();
		
    const selection = editorState.getSelection();
		
    const newContent = contentState.merge({
      blockMap: newBlockMap,
      selectionBefore: selection,
      selectionAfter: selection.merge({
        anchorKey: newBlockKey,
        anchorOffset: 0,
        focusKey: newBlockKey,
        focusOffset: 0,
        isBackward: false,
      }),
    });
    
    let newEditorState = EditorState.push(editorState, newContent, 'split-block');

jsfiddle.net/mqjxb0hr/13…。很不美观,通过新建一个内容块,再将内容块插入已有内容块来进行实现。(因为内容块是一行一行的),不满足需求。有另起一行的问题。

于是再google无果后开始翻issue,找到一个解决方法github.com/facebook/dr… 参考其中的这个后,成功解决

const currentContent = editorState.getCurrentContent();
const selection = editorState.getSelection(); 
const entityKey = Entity.create('MENTION', 'IMMUTABLE', {"text":'apple',"value":'apple',"url":'apple'}); 
const textWithEntity = Modifier.insertText(currentContent, selection, '@APPLE', null, entityKey); 
this.setState({ editorState: EditorState.push(editorState, textWithEntity, 'insert-characters') });

关键思路在于创建entity后运用官方给的modifier中的api进行对映绑定文本的插入。draftjs.org/docs/api-re… 其中关于insertText可以替换为replaceText,无伤大雅,并且在划定文本后执行插入链接操作不会报错。最后可以通过forceSelection可以显示插入链接后的光标位置,进一步优化体验。