开发需要用富文本编辑器实现一个插入链接的功能,但是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可以显示插入链接后的光标位置,进一步优化体验。