2013-09-23 7 views
6

Otrzymuję błąd z jQuery 1.10.2, ostatniego, i chciałbym wiedzieć, czy ktoś ma jakieś (inne) rozwiązanie dla ten przypadek.jQuery show() kończy się niepowodzeniem z efektem last(), after() i "blind"

Mój skrypt tworzy wiele bloków DIV (nazwanych elementów) z jednego modelu (model elementu), dodaje prąd po ostatnim i wyświetla go z efektem "niewidomym".

Oto kod, ale można go również przetestować online pod numerem 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> 

Problem jest taki sam jak: last i insertAfter().

Logika:

  • Pierwszy element jest dobrze wyświetlany i jego wpływ doszło (lub nie, kolejny błąd, ale czas mija?)
  • Podczas animacji efekt element jest zlecana ou wymienić.
  • Kolejne pozycje wstawiane są poza DOM (zdarzenie, jeśli po() powinno zostać wstawione do DOM), więc nie ma ich na stronie.

To zachowanie jest błędem z jQuery, ale muszę pokonać ten problem.

Rozwiązania wiem:

  • Nie używaj żadnego efektu.
  • Użyj kontenera i dopisz().
  • Używaj powolnego efektu zamiast ślepego. (Podziękowania dla A. Wolffa)
  • Dodaj elementy do DOM i AFTER, pokaż wszystko. (Podziękowania dla A. Wolffa)

Dziękuję wszystkim za wkład.

+1

Bizarrely, jeśli mogę umieścić swój kod w JSFiddle to działa dobrze: nie http://jsfiddle.net/TrueBlueAussie/n2UVp/ –

+3

@TrueBlueAussie jeśli masz jQuery UI http://jsfiddle.net/arunpjohny/AN3ft/1/ –

+0

@Arun P Johny: Dobrze zauważony. Problem polega na włączeniu JQueryUI. Przynajmniej to zawęża to :) –

Odpowiedz

1

Ten fragment rozwiązuje go:

$(".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

To na pewno działa, ale czy możesz wyjaśnić, dlaczego to rozwiązuje? –

+0

@TrueBlueAussie Przypuszczam, że jest to spowodowane tym, w jaki sposób jquery UI obsługuje animację. Będzie to wymagało więcej badań w celu jego debugowania. Tutaj animuję wszystkie elementy naraz, nie każde z osobna. W każdym razie animowanie zestawu elementów jest nadal lepsze niż animowanie wszystkich elementów zestawu –

1

znalazłem (jeśli racjonalne wyjaśnienie skomplikowanych) dla swojego błędu.

Przyczyna: używasz efektu jquery-ui (a nie podstawowego efektu jquery) i dodajesz elementy po ostatnim wstawionym elemencie, zanim animacja się zakończy.
Gotcha: jquery-ui używa wrapperów podczas animacji, a jeśli opakowanie jest już obecne, używa go ponownie.

Oto szczegółowa solucja:

  • Kiedy animowanie pierwszy element: na czas trwania efektu, element jest zawinięty w div z klasą ui-effects-wrapper, a to wrapper div jest animowana, aby dać blind efekt
  • Po dodaniu drugiego elementu: dodanie go po "ostatnim" (< - w tym przypadku: pierwszy element) faktycznie dodaje go wewnątrz opakowania.
  • Kiedy animowanie drugi przedmiot: jquery-ui ponowne wykorzystanie istniejącej osłony (skrót w createWrapper, patrz niżej)
  • samo dotyczy elementów 3-5
  • Po pierwsze końce animacja element owinięcie jest usunięty i zastąpiony expoprt pierwsze animowane elementy. Pozostałe elementy (pamiętajcie: zostały dołączone jako dzieci tego opakowania) kończą się zwisającymi bez rodzica.

Istotne fragmenty kodu:
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

nie sądzę, powinno to być traktowane jako błąd jquery-ui - Twój przypadek użycia jest IMHO, bardzo izolować, i nie wyobrażam sobie, co "korygujące" to wywołałoby gdzie indziej.

Solutions:

  • slideDown będzie działać (fiddle - to ożywia element, nie wrapper tam)
  • dodać <span id="beacon"></span> element i wstawić nowe elementy przed#beacon
  • A. Wolff's solution
  • jako już wiesz, .append() na wspólnym pojemniku
Powiązane problemy