2012-05-23 8 views
7

que tienen un montón de DOM comoJQuery: ¿forma elegante de reemplazar un conjunto de elementos con otro conjunto?

<div> 
    <div class="stuff"/> 
    <div class="stuff"/> 
    <div class="stuff"/> 
</div> 

y quiero reemplazarlo con un nuevo conjunto de cosas

<div> 
    <div class="stuff"/> 
    <p class="stuff"/> 
    <ul class="stuff"/> 
    <a class="stuff"/> 
</div> 

que será fue a buscar a través de Ajax. Mi pregunta es: ¿cuál es la mejor manera de hacer esto?

$.replaceWith no hace exactamente lo que quiero, porque luego termino con varias copias del nuevo stuff.

puedo garantizar que todo el stuff estarán en un bloque contiguo, y por lo que presumiblemente podría poner en algún marcador de posición después de que el último elemento (o antes del primer elemento) de la vieja stuff, quitar la vieja stuff, y vuelva a colocar el marcador de posición con el nuevo stuff.

Sin embargo, esto parece bastante indirecto y poco elegante. ¿Hay alguna manera inteligente de, eliminar todo el antiguo stuff y poner en una sola copia del nuevo stuff, todo de una vez?

EDITAR: También me gustaría hacer esto sin utilizar ningún contenedor divs. Utilizando DIV contenedor trabajarían en el caso anterior, pero fallarían en algunos casos, como cuando el stuff está dentro de un <table>:

<table> 
    <head/> 
    <body> 
     <tr/> 
     <tr class="stuff"/> 
     <tr class="stuff"/> 
     <tr class="stuff"/> 
     <tr/> 
    </body> 
</table> 

si quiero reemplazar las filas etiquetadas stuff con otro conjunto de filas, posiblemente más , posiblemente menos, no hay forma de que pueda colocarlos en un recipiente sin romper el HTML, ya que el <body> solo puede contener <tr> s (IIRC).

+0

¡Su marcado HTML parece incorrecto! – thecodeparadox

+0

¿Qué has probado que no es elegante? Hay muchas maneras de hacer esto, ¿cuál intentaste? – Joseph

+0

@thecodeparadox corrigió el marcado. Joseph: todo el marcador de posición insertar, eliminar cosas viejas, reemplazar el marcador –

Respuesta

11
$('#outerdiv').empty().append(newContent); 

A diferencia .html(), esto funcionará independientemente de si newContent es una cadena HTML, o una estructura DOM existente.

Si hay varios elementos a ser reemplazado, pero donde tiene que conservar sus hermanos, se puede hacer esto:

$('.stuff').first().before(newContent).end().remove(); 

es decir, tomar la primera .stuff elemento, agregar el nuevo contenido antes de que, a continuación, retire todos los elementos .stuff.

+0

Esto parece funcionar, y creo que pasa la prueba de" elegancia ". Gracias =) –

3

Sí: $('#tagetDiv').html(newContent)

+0

Debería haber dicho que no quiero requerir ningún contenedor div para hacer esto. Tener un contenedor div/span funciona en la mayoría de los casos, pero ocasionalmente (¡molestamente!) Falla en los bordes (divs del contenedor arruinando el formato CSS, reemplazando el cuerpo/cabeza/filas/celdas de una tabla, etc.). –

+1

@LiHaoyi si no tiene un contenedor ¿cómo se supone que debe saber qué? ¿Qué divs reemplazar? – Alnitak

+0

@Alnitak: por su clase 'cosas', que es compartida por todos los divs que quiero arrancar y reemplazar –

2

Una forma de hacerlo sería con wrapAll:

$('.stuff').wrapAll('<div/>').parent().replaceWith('<div class="stuff"/>'); 

No estoy seguro de si eso pasa la prueba "elegante", pero funciona independientemente de si hay cualquier otro contenido de la contiene elemento.

Dicho esto, sin embargo, esta parece ser una solución muy complicada para un problema simple. La solución simple sería envolver sus elementos en un elemento contenedor; esto no debería ser un problema si, como dices, puedes garantizar que siempre estarán juntos.

Cuestiones relacionadas