Tengo algunos javascript que manipulan html en función de lo que el usuario ha seleccionado. Para los navegadores reales, los métodos que estoy usando aprovechan el objeto "Rango", obtenido como tal:

    var sel = window.getSelection();
    var range = sel.getRangeAt(0);
    var content = range.toString();

La variable de contenido contiene todo el texto seleccionado, que funciona bien. Sin embargo, descubro que no puedo detectar las nuevas líneas en la cadena resultante. Por ejemplo:

El texto seleccionado es:

Abc

Def

Ghi

Range.toString () se evalúa como "abcdefghi".

Cualquier búsqueda en caracteres especiales no devuelve ninguna instancia de \ n \ f \ r o incluso \ s. Sin embargo, si escribo la variable en un control editable, los avances de línea vuelven a estar presentes.

¿Alguien sabe lo que me estoy perdiendo?

Puede ser relevante que estas selecciones y manipulaciones estén en divs editables. El mismo comportamiento es evidente en Chrome, Firefox y Opera. Sorprendentemente, IE necesita un código totalmente diferente de todos modos, pero no hay ningún problema allí, aparte de ser solo IE.

Muchas gracias.

16
Timbo 18 jul. 2009 a las 08:33

3 respuestas

La mejor respuesta

Editando mi publicación:

Experimentando un poco, encuentro que sel.toString() devuelve nuevas líneas en divs contentables, mientras que range.toString() devuelve nuevas líneas correctamente en divs no editables normales, pero no en las editables, como usted informó.

Sin embargo, no pude encontrar ninguna explicación para el comportamiento.

Este es un enlace útil http://www.quirksmode.org/dom/range_intro.html

14
T Zengerink 25 nov. 2016 a las 16:10

Gracias al OP pude hacerlo usando window.getSelection () como él sugirió. Necesitaba obtener el texto hasta la posición de intercalado en un evento de entrada, lo que me da un rango estático con el texto insertado. Entonces tengo un rango, pero no necesariamente el rango de la selección actual.

function richToPoorText(range){
    //Caso base, está colapsado.
        console.log(range);
        var restoreRange=document.createRange(); //needed for restoring the caret pos.
        restoreRange.setStart(range[0].endContainer, range[0].endOffset);
        restoreRange.setEnd(range[0].endContainer, range[0].endOffset);
        rangeClone=document.createRange();
        rangeClone.setStart(__baseEditor,0);
        rangeClone.setEnd(range[0].endContainer, range[0].endOffset);
        var str;
        var sel=window.getSelection();
        sel.removeAllRanges();
        sel.addRange(rangeClone);   //sel does converts the br to newlines
        str=sel.toString();
        sel.removeAllRanges();
        sel.addRange(restoreRange);
        return str;

}

Muchas gracias OP. Y si alguien tiene el mismo caso de uso, puede usar este fragmento

Editar: __baseEditor es una variable global que apunta al div contenteditable principal del editor

0
gabdev 22 jul. 2018 a las 00:32

Encontré al menos otras dos formas, por lo que aún puede usar el rango para encontrar la posición del cursor en Mozilla.

Una forma es llamar

var documentFragment = rangeObj.cloneContents ();

Que contiene una matriz de childNodes, y cualquier salto de línea se mostrará como un nodo de la clase "HTMLBRElement".


¡La otra forma es asegurarse de que cada etiqueta "br" vaya seguida de un carácter de nueva línea (0x0a)!

Esto no dañará el contenido HTML de ninguna manera visible, pero ahora todos los saltos HTML se traducen a saltos de línea de texto sin formato tan pronto como se llame a range.toString ().


Espero que esto ayude, incluso si este tema es muy antiguo. (Soy un nigromante de todos modos, jeje) :)

2
Gerrit Volkenborn 20 ago. 2014 a las 08:40