2013-09-23 10 views
6

Ricevo un bug da jQuery 1.10.2, l'ultimo, e vorrei sapere se qualcuno ha una (altra) soluzione per questa edizione.jQuery show() fallisce con effetto last(), after() e "blind"

Il mio script crea più blocchi DIV (elementi denominati) da un modello (modello di articolo), aggiunge il corrente dopo l'ultimo e lo visualizza con un effetto "cieco".

Questo è il codice ma è anche possibile testarlo online allo this link.

<div id="item_model" style="display: none;" class="item">MODEL</div> 
<button class="addBtn">Add 5 items</button> 

<script> 
$(".addBtn").click(function() { 
    for(var i=0; i<5; i++) { 
     // Clone model 
     var p = $("#item_model").clone(true, true); 

     // Modify item 
     p.removeAttr("id"); 
     p.text("ITEM n°"+(i+1)); 

     // Add item to the DOM 
     $(".item").last().after(p); 

     // Show item 
     $(p).show("blind"); 
     //$(p).show(); 
    } 
}); 
</script> 

Il problema è lo stesso con: last e insertAfter().

La logica:

  • Primo elemento è ben visualizzato e si è verificato il suo effetto (o non, un altro bug ma il tempo trascorre?)
  • Durante un'animazione effetto, l'elemento è in outsourcing ou sostituito.
  • Gli elementi successivi vengono inseriti fuori dal DOM (evento se after() deve essere inserito nel DOM), quindi non ci sono nella pagina.

Questo comportamento è un errore di jQuery ma devo risolvere questo problema.

Le soluzioni che so:

  • Non utilizzare alcun effetto.
  • Utilizzare un contenitore e aggiungere().
  • Utilizzare l'effetto lento anziché il buio. (Grazie a A. Wolff)
  • Aggiungi elementi al DOM e AFTER, mostra tutto. (Grazie a A. Wolff)

Grazie a tutti per il vostro contributo.

+1

Stranamente, se metto il codice in un JSFiddle funziona benissimo: http://jsfiddle.net/TrueBlueAussie/n2UVp/ –

+3

@TrueBlueAussie se non si dispone di jQuery UI http://jsfiddle.net/arunpjohny/AN3ft/1/ –

+0

@Arun P Johny: ben individuato. Quindi il problema è con l'inclusione di JQueryUI. Almeno questo lo restringe :) –

risposta

1

Questo frammento lo fissa:

$(".addBtn").click(function() { 
    var p = $("#item_model").clone(true), 
     tmp = $(); 
    p.removeAttr("id"); 
    for (var i = 0; i < 5; i++) { 
     tmp = tmp.add(p.clone(true).text("ITEM n°" + (i + 1))); 
    } 
    $(".item").last().after(tmp); 
    tmp.show("blind"); 
}); 

DEMO

+0

Che funziona sicuramente, ma puoi spiegare perché lo risolve? –

+0

@TrueBlueAussie Suppongo che questo sia dovuto a come l'interfaccia utente di jquery gestisce l'animazione. Ciò richiederà ulteriori indagini per eseguirne il debug. Qui anima tutti gli elementi contemporaneamente, non ciascuno individualmente. In ogni caso, animare set di elementi è ancora meglio di animare tutti gli elementi di un set –

1

ho trovato una spiegazione razionale (se intricato) per il bug.

La causa principale: si sta utilizzando un effetto jquery-ui (non un effetto base jquery) e si aggiungono elementi dopo l'ultimo elemento inserito, prima che l'animazione abbia terminato.
Il gotcha: jquery-ui utilizza i wrapper durante le sue animazioni e se un wrapper è già presente, lo riutilizza.

Ecco la procedura dettagliata dettagliata:

  • Durante l'animazione la prima voce: per tutta la durata degli effetti, l'elemento viene avvolto in un div con classe di ui-effects-wrapper, e questo div involucro è animato per dare il Effetto blind
  • Quando si aggiunge il secondo elemento: aggiungendolo dopo "ultimo" (- in questo caso: il primo elemento) in realtà lo aggiunge all'interno del wrapper.
  • Quando animare la seconda voce: jquery-ui riutilizza l'involucro esistente (collegamento in createWrapper, vedi sotto)
  • Lo stesso vale per gli articoli 3-5
  • Quando prime estremità di animazione, l'elemento di involucro viene rimosso e sostituito whith i primi elementi animati. Gli altri elementi (ricordiamo: sono stati attaccati come figli di questo involucro) finiscono per penzolare senza genitori.

pezzi rilevanti di codice:
jquery-ui code : snippet 1 - blind() function
jquery-ui code : snippet 2 - createWrapper() inner function
jquery-ui code : snippet 3 - blind() code when animation completes

Io non credo che questo dovrebbe essere considerato come un bug jQuery-ui - il vostro caso d'uso è, secondo me, piuttosto isolare, e non immaginerei cosa "correggendo" ciò si innescherebbe altrove.

Solutions:

  • slideDown funzionerà (fiddle - è anima l'elemento, senza involucro lì)
  • aggiungere un elemento <span id="beacon"></span> e inserire nuovi elementi prima#beacon
  • A. Wolff's solution
  • come hai già scoperto, .append() su un contenitore comune