在 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>
以下代码片段在 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>