Hay ocasiones en las que mientras trabajamos con jQuery, necesitamos obtener el HTML de un determinado objeto. Sin embargo, algo que parece sumamente sencillo, puede no serlo tanto.
Pensemos en el siguiente marcado:
<div id="header"> <ul> <li><a href="home.html">Home</a></li> <li><a href="about.html">About</a></li> <li><a href="contact.html">Contact</a></li> </ul> <div class="other_layer"> <p>Some text here...</p> </div> </div> |
Para capturar todos los elementos anteriores, bastaría con utilizar un selector básico:
var mySet = $('#header'); |
Pero si además de capturarlo, necesitamos obtener su HTML, la cosa no es tan fácil.
Con el código,
var mySetHTML = $('#header').html(); |
solo obtendríamos el HTML contenido dentro del div#header, pero no el propio div.
Para disponer de todo el HTML incluido en el objeto seleccionado, necesitamos el siguiente truco:
var mySetHTML = $('<div />').append( $('#header').clone() ).remove().html(); |
Esto funciona de la siguiente forma:
1. Clonamos el elemento que hemos seleccionado.
2. Creamos un div a modo de contenedor temporal para envolver el elemento clonado.
3. Obtenemos el HTML del nuevo div que ahora si contiene todo el marcado.
4. Una vez tenemos los datos, eliminamos el nodo del DOM para limpiarlo.
Hay que tener en cuenta que jQuery no es especialmente rápido manipulando el DOM por lo que esta operación consume recursos. Sin embargo, me he encontrado situaciones donde resulta la forma más práctica de extender una aplicación sin obligarme a reescribir parte de su arquitectura.
Si vamos a necesitar esta funcionalidad varias veces a lo largo de un código, podemos incluso convertirla en un plugin jQuery:
jQuery.fn.extend({ html2string: function() { return $('<div />').append( this.clone() ).remove().html(); } }); |
Con este pequeño plugin, capturar el HTML resultará aún más sencillo:
var mySetHTML = $('#header').html2string(); |
Hola, ¿utilizando $(‘#header’).parent().html(); no se obtiene el mismo resultado (pero sin manipular el DOM)?
Saludos
Hola Leandro,
tu fórmula es válida siempre que #header, realmente tenga padre. Sin embargo, puede darse el caso de que no sea así. Por eso, hace falta ‘inventarse’ uno temporal (el div que hemos creado) para poder acceder a su contenido.
Es por esto que algo que a priori parece muy sencillo, de repente descubres que no lo es. 🙂
Saludos!
No termino de ver la necesidad del remove(). Para quitar el elemento del DOM, vale, pero es que el elemento creado no está en el DOM, ¿no?
Hola, me he pasado revisando TODA la web porque me parece de lo más interesante (Ya la tengo en los marcadores y la seguiré de cerca) pero, o hay algo en esto que no acabo de entender o si lo que quieres es obtener el código de arriba ¿no sería más fácil usar la propiedad outerHTML del elemento DIV buscado?.
Aquí el código:
$(‘#header’)[0].outerHTML
Un saludo.
PD: Si me he equivocado en lo dicho lo siento, esque de verdad que no llego a entender lo que quieres conseguir.
Hola;
el método que indicas, outerHTML, no es estándar: fue un invento de Microsoft para manejar el DOM con anterioridad a la estandarización de este API. Es cierto que prácticamente todos los navegadores soportan este elemento pero eso no garantiza que se continúen ofreciendo soporte en el futuro.
Es por ello que, si queremos compatibilidad con todos los navegadores, y sobre todo seguir la normalización que fijan los estándares, no deberíamos usar el outerHTML nunca.
Un saludo.
Ok muchas gracias por la aclaración es que estoy empezando con javascript y cuando veo un método que está en todos los navegadores me lanzo a usar pero tendré en cuenta tu advertencia y desde ahora me lo miraré con gran cuidado.
Muchas Gracias
Buenas noches!
Muy interesante el articulo, y ya veo que es algo antiguo.
Pero aún así me veo obligado a preguntarte en que situación podría darse que #header no tenga padre, pudiendo seleccionar elementos como el mismo body o incluso el html.
Gracias!
Un saludo.
Hola;
precisamente este método se utiliza cuando puede darse el caso de que el elemento a seleccionar no tenga padre, de ahí que se recurra a un dummy que hace de contenedor.
De saber con seguridad que el elemento tiene padre, bastaría con un $(‘#header’).parent().html(); tal y como señaló Leandro en el primer comentario.
Saludos!
El problema con utilizar el código que comentan
$(‘#header’).parent().html();
Es cuando la etiqueta con id ‘header’ tiene muchas más etiquetas como hermanas, entonces el resultado no sería el de la etiqueta con id header sería todo el HTML de la etiqueta padre que puede incluir otros HTML. Espero que me haya hecho entender.
Saludos.