2012-05-07 10 views
11

Per quanto posso dire, il seguente codice dovrebbe funzionare, creando un elemento <div> e quindi creando un elemento <p>; l'espressione dovrebbe risultare in un oggetto jQuery con due elementi:jQuery dopo il metodo non funziona con elementi appena creati

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

Tuttavia, ciò che ottengo è molto diverso. The documentation (vedere l'intestazione "Inserimento di nodi DOM disconnessi") mi dice che il codice sopra dovrebbe risultare in un oggetto jQuery, afferrando entrambi gli snippet HTML e creando i due elementi DOM. Ma, quello che ho ottenuto, in diverse versioni di jQuery, tutte sopra 1.4, è un oggetto jQuery con solo 1 nodo. Tuttavia, il seguente codice funziona bene, il ritorno (quello che credo sia) l'oggetto giusto jQuery, due elementi all'interno:

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

E questo esempio funziona così:

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

Sembra che il .after() il metodo funziona correttamente se il primo nodo DOM che viene creato è vuoto, ma non quando non lo è (indipendentemente dal contenuto dei successivi nodi DOM aggiunti ad esso).

Mi manca qualcosa sugli interni di jQuery, eccentrici domini DOM e/o peculiarità JavaScript, oppure si tratta semplicemente di un bug jQuery persistente dalla versione 1.4 alla 1.7?

(Here's a meager JSFiddle dimostrando la questione abbastanza chiaramente.)

+0

Come indicato di seguito nei commenti a ** risposta elclanrs **, 'add' è un sostituto valido, e ho montato un [nuovo JSFiddle ] (http://jsfiddle.net/paulbruno/beFUF/) per dimostrare che funziona. Tuttavia, questo non spiega perché il comportamento visualizzato su [i documenti] (http://api.jquery.com/after/) (e anche i suoi commenti, vedi l'intero thread contenente le risposte da "MarkAndrewSlade") non è t disponibile per il metodo 'dopo' di oggetti jQuery di un elemento appena creato quando quell'elemento ha contenuto. –

risposta

7

Questo è stato un bug noto in jQuery < 1.9. Vedere http://bugs.jquery.com/ticket/8759

In jQuery> = 1.9, occorre ricordare la following information from the upgrade guide:

Prima di 1.9, .after(), .before(), e .replaceWith() avrebbe tentato di aggiungere o modificare i nodi nella corrente jQuery impostato se il primo nodo nel set non era collegato a un documento, e in questi casi restituisce un nuovo set jQuery piuttosto che il set originale. Questo ha creato diverse incongruenze e bug evidenti: il metodo potrebbe o non potrebbe restituire un nuovo risultato a seconda dei suoi argomenti! A partire da 1.9, questi metodi restituiscono sempre il set originale non modificato e il tentativo di utilizzare .after(), .before() o .replaceWith() su un nodo senza un genitore non ha alcun effetto - ovvero, né l'insieme né i nodi in esso contenuti vengono modificati.

+0

Grazie mille, ** Mike **. –

+2

Stranamente, sto ricevendo lo stesso bug dopo l'aggiornamento di jQuery da 1.8.2 a 1.11.0. I metodi $ .after() e $ .before() non funzionano sugli elementi appena creati. Devo innanzitutto aggiungere l'elemento appena creato al DOM e quindi inserire il nuovo contenuto in esso. Un'altra soluzione alternativa è l'utilizzo del metodo $ .add(), ma non funzionerà se si desidera inserire il contenuto prima dell'elemento. –

+0

Ho anche questo comportamento dopo l'aggiornamento a jQuery 1.10 – DrCord

6

Usa add() per aggiungere oggetti alla collezione. Io uso after() di più in elementi DOM già esistenti o memorizzati in una variabile, ma la maggior parte delle volte, se lavori con il markup dinamico, è più pratico usare l'equivalente insertAfter().

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

EDIT:

Questo funziona ...

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

Grazie, ** elclanrs **, per la risposta. Userò 'add' in futuro. E ho appena montato un [nuovo JSFiddle] (http://jsfiddle.net/paulbruno/beFUF/) per dimostrare che 'add' fa ciò che hai menzionato. Ma questo non risponde alla mia domanda, che è il motivo per cui "dopo" non lo fa. –

+0

Vedi modifica ... non so perché il bug ma funziona. – elclanrs

+0

Grazie ancora. Dato che non risponde alla mia domanda, non ti ho dato il credito di risposta, ma ho votato la tua risposta per dare il rispetto dovuto per aver trovato un nuovo pezzo di granularità nella mia domanda. –

0

ho trovato che ero ancora a volte hanno problemi con .add() al posto di .after(), quindi un altro modo semplice per aggirare questo bug è quello di fare un tiro di distanza elemento di involucro, .append() gli elementi di pari livello, e utilizzare .html() per ottenere solo il contenuto interno del wrapper.

Esempio:

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

Questo aggiungerà la <div> e <p> ma scartare il esterno <span>. Ho trovato questo funziona normalmente con .append() ma può avere problemi con .appendTo()

Problemi correlati