Javascript 在 contenteditable div 中插入 html

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6690752/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:50:32  来源:igfitidea点击:

Insert html at caret in a contenteditable div

javascriptjquerycontenteditable

提问by Niall

I have a div with contenteditable set and I am capturing keypress using jquery to call preventDefault() when the enter key is pressed. Similar to this questionwhich inserts text at the cursor, I would like to directly insert html, for brevity we'll say its a br tag. Using the answer to the question above actually works in IE as it uses the range.pasteHTML method, but in other browsers the br tag would appear as plain text and not html. How could I modify the answer to insert html and not text ?

我有一个带有 contenteditable 集的 div 并且我正在使用 jquery 捕获按键以在按下 Enter 键时调用 preventDefault() 。类似于 在光标处插入文本的这个问题,我想直接插入 html,为简洁起见,我们将其称为 br 标签。使用上述问题的答案实际上在 IE 中有效,因为它使用 range.pasteHTML 方法,但在其他浏览器中,br 标签将显示为纯文本而不是 html。如何修改答案以插入 html 而不是文本?

回答by Tim Down

In most browsers, you can use the insertNode()method of the Range you obtain from the selection. In IE < 9 you can use pasteHTML(), as you mentioned. Below is a function to do this in all major browsers. If content is already selected, it is replaced, so this is effectively a paste operation. Also, I added code to place the caret after the end of the inserted content.

在大多数浏览器中,您可以使用insertNode()从选择中获取的 Range 方法。在 IE < 9 中,您可以使用pasteHTML(),正如您所提到的。下面是在所有主要浏览器中执行此操作的函数。如果内容已经被选中,它会被替换,所以这实际上是一个粘贴操作。此外,我添加了代码以在插入的内容结束后放置插入符号。

jsFiddle: http://jsfiddle.net/jwvha/1/

jsFiddle:http: //jsfiddle.net/jwvha/1/

Code:

代码:

function pasteHtmlAtCaret(html) {
    var sel, range;
    if (window.getSelection) {
        // IE9 and non-IE
        sel = window.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 = document.createElement("div");
            el.innerHTML = html;
            var frag = document.createDocumentFragment(), node, lastNode;
            while ( (node = el.firstChild) ) {
                lastNode = frag.appendChild(node);
            }
            range.insertNode(frag);

            // Preserve the selection
            if (lastNode) {
                range = range.cloneRange();
                range.setStartAfter(lastNode);
                range.collapse(true);
                sel.removeAllRanges();
                sel.addRange(range);
            }
        }
    } else if (document.selection && document.selection.type != "Control") {
        // IE < 9
        document.selection.createRange().pasteHTML(html);
    }
}

UPDATE 21 AUGUST 2013

2013 年 8 月 21 日更新

As requested in the comments, here is an updated example with an extra parameter that specifies whether or not to select the inserted content.

根据评论中的要求,这里是一个更新的示例,带有一个额外的参数,用于指定是否选择插入的内容。

Demo: http://jsfiddle.net/timdown/jwvha/527/

演示:http: //jsfiddle.net/timdown/jwvha/527/

Code:

代码:

function pasteHtmlAtCaret(html, selectPastedContent) {
    var sel, range;
    if (window.getSelection) {
        // IE9 and non-IE
        sel = window.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 = document.createElement("div");
            el.innerHTML = html;
            var frag = document.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 = document.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();
        }
    }
}

回答by user3126867

var doc = document.getElementById("your_iframe").contentWindow.document;

// IE <= 10
if (document.selection){
    var range = doc.selection.createRange();
        range.pasteHTML("<b>Some bold text</b>");

// IE 11 && Firefox, Opera .....
}else if(document.getSelection){
    var range = doc.getSelection().getRangeAt(0);
    var nnode = doc.createElement("b");
    range.surroundContents(nnode);
    nnode.innerHTML = "Some bold text";
};

回答by delaio

by reading quickly and hoping not to be off topic, here is a track for those who, like me, need to insert code at the cursor level of a div:

通过快速阅读并希望不会偏离主题,这里有一个轨道,适合像我一样需要在 div 的光标级别插入代码的人:

document.getElementById('editeur').contentWindow.document.execCommand('insertHTML', false, '<br />');

'editeur' is iframe :

'editeur' 是 iframe :

<iframe id="editeur" src="contenu_editeur_wysiwyg.php">
</iframe>

contenu_editeur_wysiwyg.php :

contenu_editeur_wysiwyg.php :

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
</div>
</body>
</html>

don't forget :

不要忘记:

document.getElementById('editeur').contentDocument.designMode = "on";

回答by Alex G

var r = getSelection().getRangeAt(0);
r.insertNode(r.createContextualFragment('<b>Hello</b>'));

//select this range
getSelection().removeAllRanges();
getSelection().addRange(r);
//collapse to end/start 
getSelection().collapseToEnd()