使焦点在 CKEditor 5 createElement 中工作

Making focus works inside a CK Editor 5 createUIElement

所以我有一个自定义小部件,它呈现一个自定义组件。

conversion.for('editingDowncast').elementToElement({
    model: 'modelName',
    view: (modelElement, viewWriter) => {
      const modelName = modelElement.getAttribute('modelName');
      const modelNameView = viewWriter.createContainerElement('span', {
        class: 'modelName',
        'data-modelName': modelName,
      });

      const reactWrapper = viewWriter.createUIElement(
        'span',
        {
          class: 'modelName__react-wrapper',
        },
        function (this, domDocument) {
          const domElement = this.toDomElement(domDocument);

          rendermodelName(modelName, domElement);

          return domElement;
        },
      );

      viewWriter.insert(
        viewWriter.createPositionAt(modelNameView, 0),
        reactWrapper,
      );

      return toWidgetEditable(modelNameView, viewWriter);
    },
  });

其中 rendermodelName 将返回一个带有简单输入框的 React 组件

return (
    <div>
      <input type="text" />
    </div>
  );

https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/react.html.

但问题是,每当我尝试在输入中添加一些内容时,焦点就会从字段中丢失并自动移动到周围的编辑器。我错过了什么。尝试创建焦点处理程序并向其添加 modelNameView

我应该使用新的 createRawElement 吗?我当前的 CK5 是 20.0.0,所以我不希望现在出现任何重大更改。

编辑: 我研究了一点点。似乎 createRawElement 在这里不起作用。我认为这没有一个简单的解决方案。我尝试使用 allowContentOf: '$block' ,这也不能让我集中注意力。但是这些值是明确用于普通 CK 小部件,而不是用于反应组件。

我遇到了类似的问题。

CKEditor 将获取您在 Widget 上托管的 React 组件上的所有事件。

解决方法是停止将事件传播到 CKEditor,这些事件是从托管 React 组件的 DOM 元素 (domElement) 触发的。

示例代码如下: https://github.com/ckeditor/ckeditor5-core/compare/proto/input-widget#diff-44ca1561ce575490eac0d660407d5144R239

您应该停止所有必需的事件。此外,您不能在 React 组件的输入字段中粘贴任何内容。这也将被 CKEditor 的 clipboardInput 事件监听。

我遇到了同样的问题并通过将此标记添加到包装我的 Vue 组件的父 div 来解决。

https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/ui/widget-internals.html#exclude-dom-events-from-default-handlers

从 CKE 文档添加:

有时阻止默认处理程序处理事件可能很有用,例如在小部件的 UIElement 内使用 React 组件,默认情况下,小部件本身想要控制一切。为了让它成为可能,唯一要做的就是向元素或其祖先添加 data-cke-ignore-events 属性,然后在默认处理程序中将忽略由该元素的任何子元素触发的所有事件。

让我们看一个简短的例子:

<div data-cke-ignore-events="true">
    <button>Click!</button>
</div>

在上面的模板中,从包含 data-cke-ignore-events 属性的按钮调度的事件将被默认事件处理程序忽略。