0

我目前正在开发基于 slatejs 的富文本编辑器。当图像聚焦时,我需要实现在图像之后插入段落的可能性。现在,当图像具有焦点并且我按下Enter按钮时 - 什么也没发生。它应该在图像之后插入新的空段落。

示例中的相同行为https://www.slatejs.org/examples/images

任何帮助表示赞赏

4

2 回答 2

4

编辑SlateJS 提供的源代码insertImage(),我只是在函数中添加了一个段落节点。

SlateJS 来源:

const insertImage = (editor, url) => {
  const text = { text: '' }
  const image = { type: 'image', url, children: [text] }
  Transforms.insertNodes(editor, image)
}

编辑至:

const insertImage = (editor, url) => {
  const text = { text: '' }
  const image = [
    { 
      type: 'image', 
      url, 
      children: [text] 
    }, 
    {
      type: 'paragraph',
      children: [text],
    }
  ];

  Transforms.insertNodes(editor, image);
};
于 2020-08-28T15:00:57.630 回答
3

如果您选择的是空节点(图像节点),enter则默认情况下按不会添加新行。最受好评的答案仅在图像插入时添加了一个新行,这并没有解决问题。

这是一个关于如何为编辑器提供所需行为的插件。

import { Editor, Node, Path, Range, Transforms } from 'slate'

export const withCorrectVoidBehavior = editor => {
  const { deleteBackward, insertBreak } = editor

  // if current selection is void node, insert a default node below
  editor.insertBreak = () => {
    if (!editor.selection || !Range.isCollapsed(editor.selection)) {
      return insertBreak()
    }

    const selectedNodePath = Path.parent(editor.selection.anchor.path)
    const selectedNode = Node.get(editor, selectedNodePath)
    if (Editor.isVoid(editor, selectedNode)) {
      Editor.insertNode(editor, {
        type: 'paragraph',
        children: [{ text: '' }],
      })
      return
    }

    insertBreak()
  }

  // if prev node is a void node, remove the current node and select the void node
  editor.deleteBackward = unit => {
    if (
      !editor.selection ||
      !Range.isCollapsed(editor.selection) ||
      editor.selection.anchor.offset !== 0
    ) {
      return deleteBackward(unit)
    }

    const parentPath = Path.parent(editor.selection.anchor.path)
    const parentNode = Node.get(editor, parentPath)
    const parentIsEmpty = Node.string(parentNode).length === 0

    if (parentIsEmpty && Path.hasPrevious(parentPath)) {
      const prevNodePath = Path.previous(parentPath)
      const prevNode = Node.get(editor, prevNodePath)
      if (Editor.isVoid(editor, prevNode)) {
        return Transforms.removeNodes(editor)
      }
    }

    deleteBackward(unit)
  }

  return editor
}

我们覆盖该insertBreak行为(在回车时调用)并通过调用Editor.insertNode(editor, blankNode)如果所选节点为空来插入一个空行。

我们还覆盖了该deleteBackward行为。如果没有插件,在 void 节点之后删除一个空行也会删除该节点!现在,我们不是删除之前的节点,而是删除空行并选择之前的节点。

要使用此插件,您可以执行以下操作:

const editor = useMemo(() => withCorrectVoidBehavior(withReact(createEditor())), []);

我从以下位置窃取了插件代码:https ://github.com/ianstormtaylor/slate/issues/3991

于 2021-09-27T15:58:43.653 回答