2010-05-27 21 views
36

tengo un div contenteditable donde necesito para insertar texto en la posición de intercalación,Insertar texto en el cursor en un contenido div editable

Esto se puede hacer fácilmente en IE por document.selection.createRange().text = "banana"

¿Hay una forma similar de implementar esto en Firefox/Chrome?

(sé que existe una solución here, pero no se puede utilizar en div contenteditable, y se ve torpe)

Gracias!

+0

Si desea insertar código HTML en el cursor, consulte http://stackoverflow.com/questions/6690752/insert-html -at-caret-in-a-contenteditable-div – Kes115

Respuesta

110

La siguiente función insertará texto en la posición de intercalación y eliminará la selección existente. Funciona en todos los navegadores de escritorio convencionales:

function insertTextAtCursor(text) { 
    var sel, range, html; 
    if (window.getSelection) { 
     sel = window.getSelection(); 
     if (sel.getRangeAt && sel.rangeCount) { 
      range = sel.getRangeAt(0); 
      range.deleteContents(); 
      range.insertNode(document.createTextNode(text)); 
     } 
    } else if (document.selection && document.selection.createRange) { 
     document.selection.createRange().text = text; 
    } 
} 

ACTUALIZACIÓN

Basado en comentario, aquí hay algo de código para guardar y restaurar la selección. Antes de mostrar su menú contextual, debe almacenar el valor de retorno de saveSelection en una variable y luego pasar esa variable a restoreSelection para restaurar la selección después de ocultar el menú contextual y antes de insertar texto.

function saveSelection() { 
    if (window.getSelection) { 
     sel = window.getSelection(); 
     if (sel.getRangeAt && sel.rangeCount) { 
      return sel.getRangeAt(0); 
     } 
    } else if (document.selection && document.selection.createRange) { 
     return document.selection.createRange(); 
    } 
    return null; 
} 

function restoreSelection(range) { 
    if (range) { 
     if (window.getSelection) { 
      sel = window.getSelection(); 
      sel.removeAllRanges(); 
      sel.addRange(range); 
     } else if (document.selection && range.select) { 
      range.select(); 
     } 
    } 
} 
+0

Gracias por la ayuda, estoy usando esto como parte del editor de código en línea en el que cada vez que el usuario escribe "." después de un nombre de objeto, aparece un menú contextual con una lista de sus métodos (intellisense/código completado) Y cuando el usuario hace clic en un nombre de método, el texto debe pegarse después del punto en el área de código div. Pero hasta ahora el "nombre del método" se pega dentro del menú contextual no dentro del área de código. – user314362

+1

OK. En ese caso, le sugiero que guarde una copia del Rango/Rango de texto que representa la selección en el punto en el que está a punto de mostrar el menú contextual y luego restaure la selección luego de ocultar el menú contextual pero antes de insertar el texto. –

+0

Ver mi respuesta actualizada. –

-2

simplemente un método más sencillo con jQuery:

copia todo el contenido del div

var oldhtml=$('#elementID').html();

var tobejoined='<span>hii</span>';

//element with new html would be

$('#elementID').html(oldhtml+tobejoined);

simple!

+1

No resuelve la pregunta inicial, agrega el texto después del contenido del html. – Tobi

0
  1. Obtiene un objeto de selección con window.getSelection().
  2. Use Selection.getRangeAt(0).insertNode() para agregar un textonodo.
  3. Si es necesario, mueva la posición del cursor detrás del texto agregado con Selection.modify(). (No estandarizada, pero esta función es compatible con Firefox, Chrome y Safari)

    function insertTextAtCursor(text) 
    { 
        let selection = window.getSelection(); 
        let range = selection.getRangeAt(0); 
        range.deleteContents(); 
        let node = document.createTextNode(text); 
        range.insertNode(node); 
    
        for(let position = 0; position != text.length; position++) 
        { 
         selection.modify("move", "right", "character"); 
        }; 
    } 
    
Cuestiones relacionadas