document.execCommand('insertHTML') 的奇怪行为

Weird behaviour with document.execCommand('insertHTML')

我正在尝试通过添加 CSS class 以编程方式突出显示搜索词的所有出现,如下所示:

const style = document.createElement('style');
style.setAttribute('type', 'text/css');
style.innerHTML = `
.word-occurence {
  background: yellow;
  color: red;
  font-weight: bold;
  cursor: pointer;
}
`;
document.head.append(style)

document.designMode = "on";

window.getSelection().collapse(document, 0);

const word = 'Ubuntu';

while (window.find(word)) {
  document.execCommand('insertHTML', false, '<span class="word-occurence">' + window.getSelection() + '</span>');
  window.getSelection().collapseToEnd();

}
document.designMode = "off";

它几乎完美运行。当我在 Ubuntu 上的 Apache 服务器的默认 HTML 上尝试此操作时(可以在此处找到:http://bl.ocks.org/SunDi3yansyah/raw/c8e7a935a9f6ee6873a2/),所有出现的单词“Ubuntu”都变成了红色在黄色背景上,但其中一个(第 4 个也就是他段落开头的那个)得到了 CSS 内联样式而不是 class。它缺少 cursor: pointer 并且多了一个 font-size: 14.6667px;

我知道 document.execCommand 已被弃用,但我非常好奇:那里发生了什么?

在最新的 Chrome 版本中很容易发现这个错误。 insertHTML 命令在更改甚至删除 [span] 等内联元素的属性时存在错误。在您的情况下,它会破坏作为文本节点第一个单词的任何单词出现的属性。

没有官方规范,但有大量关于可能的错误和解决方法的信息。例如,我根据此 post 的一些建议,通过将 [span] 标记替换为 [em] 标记来修复您的代码:Is there a way to keep execCommand("insertHTML") from removing attributes in chrome?

固定部分:

document.execCommand('insertHTML', false, '<em class="word-occurence">' + window.getSelection() + '</em>');

作为一个副作用,由于标签本身,单词变成了斜体,但是 class 属性现在可以完美地工作——没有额外的字体大小和诸如此类的东西。说到额外的字体大小。我不仅在第 4 次出现 Ubuntu 这是 [p] 标签的第一个词时发现了问题。位于自己的 [span] 元素内的徽标附近的第一个词也受到此错误的影响。

综上所述,insertHTML 在使用 [span] 标签时存在各种错误。

以下是有关此主题的一些附加信息:https://w3c.github.io/editing/docs/execCommand/#fix-disallowed-ancestors