【问题标题】:Insert text in Javascript contenteditable div在 Javascript contenteditable div 中插入文本
【发布时间】:2010-09-20 02:39:38
【问题描述】:
有没有办法将文本(字符串,可能有也可能没有html标签)插入div?
它必须是div 而不是textarea。
首先,我需要获取光标位置,然后在该位置插入文本。类似于insertAdjacentText函数,但只能在标签之前或之后插入,并且只能在IE中使用。
请参阅此网址:http://yart.com.au/test/iframe.aspx。注意如何将光标定位在 div 中,我们需要在光标位置添加文本。
【问题讨论】:
标签:
javascript
contenteditable
text-cursor
【解决方案1】:
如果您只需要在当前选择/插入点插入 HTML,这是可行的。在我的脑海中(让你开始):
- 在 IE 中,使用
document.selection.createRange().pasteHTML(theNewHTML)。
- 在其他浏览器中,您应该可以使用
document.execCommand("InsertHTML", ...)。
我只在可编辑的 iframe/文档中使用了这些技术,而不是在 div 中,但我相信,如果 div 被聚焦,这些调用应该可以工作。
正如另一个答案所警告的那样,如果您想要更细粒度的控制(例如在其他地方插入文本),它会变得很难看。
【解决方案2】:
范围和选择对象
使用selection 和range objects。这些包含有关当前选择的各种信息,以及它在节点树中的位置。
公平警告:
完成您所描述的事情并非完全不可能,但如果您非常喜欢,您将陷入浏览器怪癖和不兼容性 的深渊。您将不得不进行大量对象检测,检查以确保您拥有一致的值和方法。在开发过程中逐步检查所有浏览器。祝你好运!
【解决方案3】:
这是一个跨浏览器示例,改编自 this answer 以使用 iframe。
function pasteHtmlAtCaret(html, selectPastedContent, iframe) {
var sel, range;
var win = iframe ? iframe.contentWindow : window;
var doc = win.document;
if (win.getSelection) {
// IE9 and non-IE
sel = win.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// only relatively recently standardized and is not supported in
// some browsers (IE9, for one)
var el = doc.createElement("div");
el.innerHTML = html;
var frag = doc.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
var firstNode = frag.firstChild;
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
if (selectPastedContent) {
range.setStartBefore(firstNode);
} else {
range.collapse(true);
}
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if ( (sel = doc.selection) && sel.type != "Control") {
// IE < 9
var originalRange = sel.createRange();
originalRange.collapse(true);
sel.createRange().pasteHTML(html);
if (selectPastedContent) {
range = sel.createRange();
range.setEndPoint("StartToStart", originalRange);
range.select();
}
}
}
【解决方案4】:
您还可以使用 insertImage 的迂回方法。您使用 execCommand "insertImage" 插入一个假图像(或一个小图像),然后使用 Javascript 替换 innerHTML 以添加文本。
例如:
iFrame.focus()
iFrame.document.execCommand("insertImage", "", "fakeimage.jpg")
iFrame.document.body.innerHTML=iFrame.document.body.innerHTML.replace("<img src=\"fakeimage.jpg\">", "MY CUSTOM <b>HTML</b> HERE!")
而 iFrame 等于预期 iFrame 的 id。或者,您可以通过 document.getElementById("IDofDIVlayer").innerHTML
使用 DIV 层
调用execCommand前一定要对焦,否则在IE下可能不起作用。
此方法在 IE 中也适用。经过测试。