javascript 有没有办法防止 execCommand("insertHTML") 删除 chrome 中的属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25941559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to keep execCommand("insertHTML") from removing attributes in chrome?
提问by sonicblis
Context is Chrome 37.0.2062.120 m.
上下文是 Chrome 37.0.2062.120 m。
I'm using execCommand to insert html into an editable div. My execCommand call looks like this:
我正在使用 execCommand 将 html 插入到可编辑的 div 中。我的 execCommand 调用如下所示:
function insertHTML(){
document.execCommand('insertHTML', false, '<span id="myId">hi</span>');
}
When the editable div looks like this:
当可编辑的 div 看起来像这样时:
<div contenteditable="true">
some [insertion point] content
</div>
and I use execCommand to insert html into a contenteditable div, all of the attributes of the HTML are inserted as expected and I end up with this:
我使用 execCommand 将 html 插入到 contenteditable div 中,HTML 的所有属性都按预期插入,最后我得到了这个:
<div contenteditable="true">
some <span id="myId">hi</span> content
</div>
When, however, I insert the exact same html into this structure:
但是,当我将完全相同的 html 插入到这个结构中时:
<div contenteditable="true">
some content
<div>more [insertion point] content</div>
</div>
The attributes are removed from the span being inserted and it ends up looking like this:
这些属性从被插入的跨度中删除,最终看起来像这样:
<div contenteditable="true">
some content
<div>more <span style="font-size: 10pt;">hi</span> content</div>
</div>
Is there any way to keep this from happening?
有什么办法可以防止这种情况发生吗?
回答by Tim Down
In this particular case I would suggest using Range.insertNode
instead, which will give you total control of what gets inserted:
在这种特殊情况下,我建议Range.insertNode
改为使用,这将使您完全控制插入的内容:
function insertHTML() {
var sel, range;
if (window.getSelection && (sel = window.getSelection()).rangeCount) {
range = sel.getRangeAt(0);
range.collapse(true);
var span = document.createElement("span");
span.id = "myId";
span.appendChild( document.createTextNode("hi") );
range.insertNode(span);
// Move the caret immediately after the inserted span
range.setStartAfter(span);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
function isOrIsAncestorOf(ancestor, descendant) {
var n = descendant;
while (n) {
if (n === ancestor) {
return true;
} else {
n = n.parentNode;
}
}
return false;
}
function nodeContainsSelection(node) {
var sel, range;
if (window.getSelection && (sel = window.getSelection()).rangeCount) {
range = sel.getRangeAt(0);
return isOrIsAncestorOf(node, range.commonAncestorContainer);
}
return false;
}
function insertHTML() {
var sel, range;
if (window.getSelection && (sel = window.getSelection()).rangeCount) {
range = sel.getRangeAt(0);
range.collapse(true);
var span = document.createElement("span");
span.id = "myId";
span.appendChild( document.createTextNode("hi") );
range.insertNode(span);
// Move the caret immediately after the inserted span
range.setStartAfter(span);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
window.onload = function() {
document.getElementById("inserter").onmousedown = function() {
var editor = document.getElementById("editor");
if (nodeContainsSelection(editor)) {
insertHTML();
return false;
}
};
};
span {
font-weight: bold;
color: green;
}
<input type="button" id="inserter" value="Insert span">
<div contenteditable="true" id="editor">
some content
</div>
回答by Soferio
One solution might be to not use span, i.e. use a non-span element. I have used the element <em>
instead, to solve a similar problem with Chrome, because italics is fine by me - and as a consequence the <span>
-fiddling "bug" in Chrome does not affect me. See discussion here: Discussion re CKEdit bug, but relevant here too
一种解决方案可能是不使用跨度,即使用非跨度元素。我已经使用该元素<em>
来解决 Chrome 的类似问题,因为斜体对我来说很好 - 因此<span>
,Chrome 中的 -摆弄“错误”不会影响我。请参阅此处的讨论:关于 CKEdit 错误的讨论,但此处也有相关性