document.execCommand('insertHTML')

问题描述

我正在尝试通过添加这样的 CSS 类以编程方式突出显示搜索词的所有出现:

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”这个词在黄色背景上都变成了红色,但其中一个(第四个)也就是他段落开头的那个)获得了 CSS 内联样式而不是类。它缺少 cursor: pointer 并且有一个额外的 font-size: 14.6667px;

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

解决方法

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

没有官方规范,但有很多关于可能的错误和解决方法的信息。例如,我按照这篇文章的一些建议通过将 [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>');

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

总而言之,insertHTML 在使用 [span] 标签时存在各种错误。

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