在更改背景颜色时,在 CKEditor 中重用具有自定义属性的现有跨度

Reusing existing span with custom attributes in CKEditor while changing background color

更改背景颜色时,CKEditor 将所选内容包装在设置了内联样式的 span 元素中。

我有一个创建交互式视频的应用程序:可以在需要的时刻停止播放,在这些暂停中,观众可以跳转到视频的关键时刻,或回答测验,返回到特定点如果答案错误,则播放视频等等。为了在播放器上方创建这个交互层,我使用带有一些自定义插件的 CKEditor 来创建交互元素。

其中一个插件用于创建具有自定义属性 span 的元素 data-player-control:

span[data-player-control] {
    background-color: #3366FF;
    color: #FFF;
    border-radius: 10px;
    padding: 10px;
}
<span data-player-control="play">My element</span>

data-player-control属性的值不固定(可以在插件中指定),用于控制视频的显示。

当使用编辑器更改元素背景颜色时,它会将元素文本包装在新的 span 中,结果为:

span[data-player-control] {
    background-color: #3366FF;
    color: #FFF;
    border-radius: 10px;
    padding: 10px;
}
<span data-player-control="play">
  <span style="background-color:#FF0000">My element</span>
</span>

这两个嵌套的 span 元素,具有两种不同的背景颜色,是不需要的。

我需要的是应用于现有 span 元素的内联样式,结果是:

span[data-player-control] {
    background-color: #3366FF;
    color: #FFF;
    border-radius: 10px;
    padding: 10px;
}
<span data-player-control="play" style="background-color:#FF0000">
  My element
</span>

如何实现?

使用 dataFilter 或 htmlFilter 不是可行的解决方案,因为当进入或存在 CKEditor 的内联实例时,它们在输入或输出数据中执行。使用转换也不是解决方案,因为它使用简化形式来表示元素,而不是真正的 DOM.

在编辑内容时是否有回调函数可以使用(所以我可以根据需要更改DOM)?

您可以尝试使用用于添加背景颜色的自定义样式定义。 colorButton_backStyle 可以在编辑器配置中设置。

要用一些自定义属性覆盖 span 元素,您可以使用:

config.colorButton_backStyle = {
    element: 'span',        
    styles: { 'background-color': '#(color)' },
    overrides: { 'element': 'span', attributes: { 'data-player-control': 'play' } }
};

所以基本上 overrides 属性是在应用背景颜色时使用的,并且有一个具有此类属性的跨度 - 它被替换(但随后该属性也被删除)。您可以添加 属性 :

config.colorButton_backStyle = {
    element: 'span',
    attributes: { 'data-player-control': 'play' },
    styles: { 'background-color': '#(color)' },
    overrides: { 'element': 'span', attributes: { 'data-player-control': 'play' } }
};

所以那个overriding span也有你的属性。此解决方案的问题在于:

  1. 将背景颜色应用到其他元素时,span 也将具有 data-player-control 属性。
  2. 删除背景颜色时,整个范围都会被删除。

以上解决方案可能不符合您的需要。也许对您要解决的问题有不同的方法?

据我从问题中了解到,您希望 HTML 始终定义结构(不仅作为输出数据),对吗?嵌套跨度的结构在您的 application/implementation 中导致什么问题?

一个简单的解决方案是在编辑器实例中监听change事件,然后根据需要修改event.editor.ui.contentsElement.$中的DOM。