如何在 ckeditor5 小部件中为输入制作可编辑标签?
How do I make an editable label for an input, within a ckeditor5 widget?
这是一些示例HTML我正在尝试制作:
<div>
<input type="checkbox" id="checkbox_1" name="checkbox_1" />
<label for="checkbox_1"></label>
</div>
这是我的 downcast 转换器:
conversion.for( 'downcast' ).elementToElement( {
model: 'checkbox',
view: ( modelElement, viewWriter ) => {
const div = viewWriter.createContainerElement( 'div', {} );
const input = viewWriter.createEmptyElement( 'input', {'type': 'checkbox'} );
const label = viewWriter.createEditableElement( 'label', {} );
viewWriter.insert( viewWriter.createPositionAt( div, 0 ), input );
viewWriter.insert( viewWriter.createPositionAt( div, 1 ), label );
return toWidgetEditable( div, viewWriter );
}
} );
在 CKEditor 5 检查器中,我可以看到视图呈现如下:
<div contenteditable="true" class="ck-editor__editable ck-editor__nested-editable">
<input type="checkbox" />
<label>
</label>
</div>
在编辑器中,我无法向标签或周围添加文本 div。
如果我将 div
声明从 createContainerElement
更改为 createEditableElement
,我可以在 div 中插入文本,但我仍然无法编辑标签。
如何设置转换器以便我可以将可编辑的标签附加到我的 <input>
?我试过查看 ckeditor5-list
中的 todolist
代码,但它根本没有使用 conversion.for
或 elementToElement
,所以我有点迷路了。
您发布的代码不正确,因为您无法突然创建这样的视图元素。如果它们应该是可编辑的,则需要将它们映射到模型中的某些内容。除非这应该是一个不可编辑的区域。在这种情况下,您应该使用 toWidget()
而不是 toWidgetEditable()
.
第二个问题是在编辑器中使用可聚焦字段必须非常小心。此类元素必须位于小部件的不可编辑部分内,此外,您需要阻止编辑器处理它们的事件。目前,这只能通过破解来实现:
// Hack needed to make the input fields accessible and responsive when used in a widget.
function preventCKEditorHandling( domElement, editor ) {
// Prevent the editor from listening on below events in order to stop rendering selection.
domElement.addEventListener( 'click', stopEventPropagationAndHackRendererFocus, { capture: true } );
domElement.addEventListener( 'mousedown', stopEventPropagationAndHackRendererFocus, { capture: true } );
domElement.addEventListener( 'focus', stopEventPropagationAndHackRendererFocus, { capture: true } );
// Prevents TAB handling or other editor keys listeners which might be executed on editors selection.
domElement.addEventListener( 'keydown', stopEventPropagationAndHackRendererFocus, { capture: true } );
function stopEventPropagationAndHackRendererFocus( evt ) {
evt.stopPropagation();
// This prevents rendering changed view selection thus preventing to changing DOM selection while inside a widget.
editor.editing.view._renderer.isFocused = false;
}
这是一些示例HTML我正在尝试制作:
<div>
<input type="checkbox" id="checkbox_1" name="checkbox_1" />
<label for="checkbox_1"></label>
</div>
这是我的 downcast 转换器:
conversion.for( 'downcast' ).elementToElement( {
model: 'checkbox',
view: ( modelElement, viewWriter ) => {
const div = viewWriter.createContainerElement( 'div', {} );
const input = viewWriter.createEmptyElement( 'input', {'type': 'checkbox'} );
const label = viewWriter.createEditableElement( 'label', {} );
viewWriter.insert( viewWriter.createPositionAt( div, 0 ), input );
viewWriter.insert( viewWriter.createPositionAt( div, 1 ), label );
return toWidgetEditable( div, viewWriter );
}
} );
在 CKEditor 5 检查器中,我可以看到视图呈现如下:
<div contenteditable="true" class="ck-editor__editable ck-editor__nested-editable">
<input type="checkbox" />
<label>
</label>
</div>
在编辑器中,我无法向标签或周围添加文本 div。
如果我将 div
声明从 createContainerElement
更改为 createEditableElement
,我可以在 div 中插入文本,但我仍然无法编辑标签。
如何设置转换器以便我可以将可编辑的标签附加到我的 <input>
?我试过查看 ckeditor5-list
中的 todolist
代码,但它根本没有使用 conversion.for
或 elementToElement
,所以我有点迷路了。
您发布的代码不正确,因为您无法突然创建这样的视图元素。如果它们应该是可编辑的,则需要将它们映射到模型中的某些内容。除非这应该是一个不可编辑的区域。在这种情况下,您应该使用 toWidget()
而不是 toWidgetEditable()
.
第二个问题是在编辑器中使用可聚焦字段必须非常小心。此类元素必须位于小部件的不可编辑部分内,此外,您需要阻止编辑器处理它们的事件。目前,这只能通过破解来实现:
// Hack needed to make the input fields accessible and responsive when used in a widget.
function preventCKEditorHandling( domElement, editor ) {
// Prevent the editor from listening on below events in order to stop rendering selection.
domElement.addEventListener( 'click', stopEventPropagationAndHackRendererFocus, { capture: true } );
domElement.addEventListener( 'mousedown', stopEventPropagationAndHackRendererFocus, { capture: true } );
domElement.addEventListener( 'focus', stopEventPropagationAndHackRendererFocus, { capture: true } );
// Prevents TAB handling or other editor keys listeners which might be executed on editors selection.
domElement.addEventListener( 'keydown', stopEventPropagationAndHackRendererFocus, { capture: true } );
function stopEventPropagationAndHackRendererFocus( evt ) {
evt.stopPropagation();
// This prevents rendering changed view selection thus preventing to changing DOM selection while inside a widget.
editor.editing.view._renderer.isFocused = false;
}