2012-05-07 18 views
11

Hasta donde sé, el siguiente código debería funcionar, creando un elemento <div> y luego creando un elemento <p>; la expresión debe resultar en un objeto jQuery con dos elementos:El método posterior de jQuery no funciona con los elementos recién creados

$("<div>first element's content</div>").after("<p>second element's content</p>"); 

Sin embargo, lo que consigo es muy diferente. The documentation (consulte el encabezado "Insertar nodos de DOM desconectados") me dice que el código anterior debería dar como resultado un objeto jQuery, capturar tanto fragmentos de código HTML como crear los dos elementos DOM. Pero, lo que he obtenido, en varias versiones diferentes de jQuery, todas por encima de 1.4, es un objeto jQuery con solo 1 nodo. Sin embargo, el siguiente código funciona bien, volviendo (lo que creo que es) el objeto correcto jQuery, dos elementos en el interior:

$("<div></div>").after("<p>second element's content</p>"); 

Y este ejemplo funciona así:

$("<div></div>").after("<p>second element's content</p>").after("<p>third element's content</p>"); 

parece que el .after() El método funciona bien si el primer nodo DOM que se está creando está vacío, pero no cuando no lo está (independientemente del contenido de los nodos DOM posteriores que se le añaden).

¿Me falta algo sobre el funcionamiento interno de jQuery, peculiaridades DOM y/o peculiaridades de JavaScript, o es simplemente un error jQuery que persiste desde la versión 1.4 hasta la 1.7?

(Here's a meager JSFiddle demostrando el tema muy claramente.)

+0

Como se menciona a continuación en los comentarios ** respuesta de ** elclanrs, 'add' es un sustituto viable, y he batido un [nuevo JSFiddle ] (http://jsfiddle.net/paulbruno/beFUF/) para demostrar que funciona. Sin embargo, esto no explica por qué el comportamiento mostrado en [los documentos] (http://api.jquery.com/after/) (e incluso sus comentarios, vea el hilo completo que contiene las respuestas de "MarkAndrewSlade") no es t disponible para el método 'after' de objetos jQuery de un elemento creado recientemente cuando ese elemento tiene contenido. –

Respuesta

7

Esto fue un error conocido en jQuery < 1.9. Ver http://bugs.jquery.com/ticket/8759

En jQuery> = 1.9, la following information from the upgrade guide hay que señalar:

Antes de 1,9, .after(), .before() y .replaceWith() trataría de añadir o cambiar los nodos en la corriente jQuery establecer si el primer nodo en el conjunto no estaba conectado a un documento, y en esos casos devuelve un nuevo conjunto jQuery en lugar del conjunto original. Esto creó varias inconsistencias y errores: el método podría o no devolver un nuevo resultado según sus argumentos. A partir de 1.9, estos métodos siempre devuelven el conjunto original sin modificar e intentar usar .after(), .before(), o .replaceWith() en un nodo sin un padre no tiene ningún efecto, es decir, ni el conjunto ni los nodos que contiene cambian.

+0

Muchas gracias, ** Mike **. –

+2

Extrañamente, estoy obteniendo este mismo error después de actualizar jQuery de 1.8.2 a 1.11.0. Los métodos $ .after() y $ .forefore() no funcionan en los elementos recién creados. Primero necesito agregar el elemento recién creado a DOM y luego insertar el nuevo contenido en él. Otra solución es utilizar el método $ .add(), pero no funcionará si desea insertar contenido antes del elemento. –

+0

También aparece este comportamiento después de actualizar a jQuery 1.10 – DrCord

6

Uso add() para añadir objetos a la colección. Uso after() más en los elementos DOM que ya existen o que están en caché en una variable, pero la mayoría de las veces, si trabaja con marcado dinámico es más práctico usar el equivalente insertAfter().

$("<div>first element's content</div>").add("<p>second element's content</p>"); 

EDIT:

Esto funciona ...

var $el = $('<div/>', { 
    text: 'hey there' 
}).after('<p>Lorem</p>'); 
+0

Gracias, ** elclanrs **, por su respuesta. Usaré 'add' en el futuro. Y acabo de crear un [nuevo JSFiddle] (http://jsfiddle.net/paulbruno/beFUF/) para demostrar que 'add' hace lo que mencionaste. Pero esto no responde a mi pregunta, por lo que 'after 'no lo hace. –

+0

Ver edición ... no sé por qué el error pero eso funciona. – elclanrs

+0

Gracias de nuevo. Como no responde mi pregunta, no le he otorgado crédito de respuesta, pero he votado positivamente su respuesta para dar el debido respeto por la búsqueda de una nueva granularidad en mi pregunta. –

0

me pareció que estaba todavía a veces tienen problemas con .add() en lugar de .after(), por lo que otra manera fácil de conseguir evitar este error es hacer un tiro de elemento de envoltura, .append() los elementos relacionados, y utilizar .html() para obtener sólo el contenido interno de la envoltura.

Ejemplo:

$('body').append(
    $('<span/>').append(
     $("<div>first element's content</div>") 
    ).append(
     $("<p>second element's content</p>") 
    ).html() 
); 

Esto añadirá la <div> y <p> pero descartar el exterior <span>. He encontrado que esto generalmente funciona bien con .append() pero puede tener problemas con .appendTo()

Cuestiones relacionadas