2011-02-04 14 views
12

¿Hay alguna manera de obtener la cadena html de un objeto de rango de JavaScript en los navegadores compatibles con W3C?Conversión de rango o fragmento de documento en la cadena

Por ejemplo, digamos que el usuario selecciona la siguiente: Hello <b>World</b>
Es posible conseguir "Hello World" como una cadena utilizando el método Range.toString(). (En Firefox, también es posible utilizar el documento 's getSelection método.)

Pero me parece que no puede encontrar una manera de obtener el código HTML interno.

Después de algunas búsquedas, he encontrado que el rango se puede convertir en un objeto DocumentFragment.

Pero DocumentFragments no tienen innerHTML propiedad (al menos en Firefox, no han intentado Webkit u Opera).
Lo que me parece extraño: parecería obvio que debería haber alguna forma de acceder a los elementos seleccionados.

Me doy cuenta de que puedo crear un documentFragment, anexar el fragmento del documento a otro elemento, y luego obtener el innerHTML de ese elemento.
Pero ese método cerrará automáticamente cualquier etiqueta abierta dentro del área que seleccione.
Además de eso, seguramente hay una "mejor manera" obvia que unirlo al dom solo para obtenerlo como una cadena.

Entonces, ¿cómo obtener la cadena del html de un rango o DocFrag?

Respuesta

3

No, esa es la única forma de hacerlo. Las especificaciones DOM Level 2 de hace aproximadamente 10 años no tenían casi nada en términos de serialización y deserialización de nodos desde y hacia el texto HTML, por lo que estás obligado a confiar en extensiones como innerHTML.

En cuanto a su comentario de que

Pero ese método de auto cierre todas las etiquetas abiertos dentro del área que seleccione.

... ¿de qué otro modo podría funcionar? El DOM está formado por nodos dispuestos en un árbol. Copiar contenido del DOM solo puede crear otro árbol de nodos. Los nodos de elementos están delimitados en HTML por un comienzo y, a veces, una etiqueta de finalización. Una representación HTML de un elemento que requiere una etiqueta final debe tener una etiqueta final, de lo contrario no es HTML válido.

+0

Las etiquetas finales se crean cuando el intervalo se convierte en un fragmento de documento (ISN' ¿Eso es correcto?). Sin embargo, ** debería ** ser posible averiguar qué está contenido en el rango antes de que se convierta en nodos, incluso si el rango contiene marcas no válidas. – SamGoody

+4

No estoy de acuerdo. Cuando se analiza el marcado no válido, el navegador lo maneja como lo crea conveniente y crea los nodos apropiados en el DOM, que es la representación del documento por parte del navegador. Ese marcado inválido esencialmente se descarta, al menos en lo que respecta al DOM (que es a lo que JavaScript puede acceder).Debes dejar de pensar en el DOM en términos de una cadena y empezar a pensar en él como un árbol. Las etiquetas de finalización son un producto de la serialización de este árbol a una cadena HTML (como por ejemplo 'innerHTML'). No existen como entidades dentro del árbol. –

4

Para explicar un ejemplo de here:

//Example setup of a fragment 
var frag = document.createDocumentFragment(); //make your fragment 
var p = document.createElement('p'); //create <p>test</p> DOM node 
p.textContent = 'test'; 
frag.appendChild(p ); 

//Outputting the fragment content using a throwaway intermediary DOM element (div): 
var div = document.createElement('div'); 
div.appendChild(frag.cloneNode(true)); 
console.log(div.innerHTML); //output should be '<p>test</p>' 
+1

Ese es el enfoque descrito en la pregunta. El OP quiere una mejor manera (que lamentablemente no existe). –

10

Fwiw, la forma jQuery:

$('<div>').append(fragment).html() 
Cuestiones relacionadas