在 Chrome 中使用 document.execCommand("insertorderedlist") 丢失样式

Styles getting lost using document.execCommand("insertorderedlist") in Chrome

以下代码片段在 Chrome 上丢失了自定义样式,但在 Firefox 上没有:

    document.getElementById( 'run' ).addEventListener( 'click', function() {
      document.execCommand("insertorderedlist");
    } );
  <div contenteditable="true">
    <p><span style="font-weight: bold;">line 1</span></p>
    <p><span style="font-style: italic;">line 2</span></p>
    <p><span style="text-decoration-line: underline;">line 3</span></p>
  </div>
  
  <button id="run">Select the above text and click me</button>

是否有已知的解决方法?我找不到任何关于它的文档。

您需要获取选择共同祖先的样式(在本例中,它是一个文本节点,因此您必须获取 parentNode),并将其应用于新的选择共同祖先:

document.getElementById( 'run' ).addEventListener( 'click', function() {
        sel = window.getSelection();
        if (sel.rangeCount) {
            let selection = sel.getRangeAt(0);
            if (selection.startContainer.parentNode.tagName === 'SPAN') {
              let startNode = selection.startContainer.parentNode.parentNode;
              let endNode = selection.endContainer.parentNode.parentNode;
              let styles = [startNode.firstChild.style.cssText];
              while(startNode && !startNode.isEqualNode(endNode)) {
                  startNode = startNode.nextElementSibling || startNode.nextSibling;
                  styles.push(startNode.firstChild.style.cssText);
              }
              document.execCommand("insertorderedlist");
              selection = sel.getRangeAt(0);
              startNode = selection.startContainer.parentNode;
              endNode = selection.endContainer.parentNode;
              newNodes = [startNode];
              while(startNode && !startNode.isEqualNode(endNode)) {
                  startNode = startNode.nextElementSibling || startNode.nextSibling;
                  newNodes.push(startNode);
              }
              for (var i = 0; i < newNodes.length; i++) {
                 newNodes[i].style = styles[i];
              }
            } else {
              if (sel.rangeCount) {
                  let ancestor = sel.getRangeAt(0).commonAncestorContainer.parentNode;
                  document.execCommand("insertorderedlist");
                  sel.getRangeAt(0).commonAncestorContainer.parentNode.style = ancestor.style.cssText;
              }
          }
        }
        
    } );
<div contenteditable="true">
    <p><span style="font-weight: bold;">line 1</span></p>
    <p><span style="font-style: italic;">line 2</span></p>
    <p><span style="text-decoration-line: underline;">line 3</span></p>
  </div>
  
  <button id="run">Select the above text and click me</button>