Inserte html en el cursor en un div contento

Resuelto Niall asked hace 13 años • 4 respuestas

Tengo un div con un conjunto contenteditable y estoy capturando la pulsación de teclas usando jquery para llamar a preventDefault() cuando se presiona la tecla Intro. De manera similar a esta pregunta que inserta texto en el cursor, me gustaría insertar html directamente; para abreviar, diremos que es una etiqueta br. Usar la respuesta a la pregunta anterior realmente funciona en IE, ya que utiliza el método range.pasteHTML, pero en otros navegadores la etiqueta br aparecería como texto sin formato y no como html. ¿Cómo podría modificar la respuesta para insertar html y no texto?

Niall avatar Jul 14 '11 15:07 Niall
Aceptado

En la mayoría de los navegadores, puede utilizar el insertNode() método del Rango que obtiene de la selección. En IE <9 puedes usar pasteHTML(), como mencionaste. A continuación se muestra una función para hacer esto en los principales navegadores. Si el contenido ya está seleccionado, se reemplaza, por lo que en realidad se trata de una operación de pegado. Además, agregué código para colocar el cursor después del final del contenido insertado.

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

Código:

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);
    }
}

ACTUALIZACIÓN 21 DE AGOSTO DE 2013

Como se solicitó en los comentarios, aquí hay un ejemplo actualizado con un parámetro adicional que especifica si se selecciona o no el contenido insertado.

Demostración: http://jsfiddle.net/timdown/jwvha/527/

Código:

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();
        }
    }
}
Tim Down avatar Jul 14 '2011 09:07 Tim Down
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";
};
user3126867 avatar Dec 21 '2013 13:12 user3126867