2013-01-09 23 views
7

Wystąpił problem z próbą załadowania "spinnera" na mojej stronie, która działa podczas sortowania tabeli, szczególnie dla wolniejszych klientów, ponieważ może to zająć do 10 sekund, aby posortuj stronę. Widzę, że DOM zostaje zmodyfikowany za pomocą kodu przędzarki, ale nie wyświetla się. Miałem nadzieję, że może być coś, co mogę zrobić, żeby wymusić pokaz tarczy przed tym rodzajem, i oczywiście zatrzymać, kiedy sortowanie zostanie zakończone.jQuery: wymuszenie wyświetlania zmodyfikowanego domena

Mój sort jest oparty na 'sorttable.js', który zmodyfikowałem, aby obsługiwać sortowanie wtórne w pierwszej kolumnie tabeli (z nazwami w nim).

Mój spinner używa 'spin.js'.

Wciąż jestem nowicjuszem z tego materiału jQuery, a ten sortowalny kod jest raczej zaangażowany. Podświetlam fragmenty poniżej, ale mój pełny zmodyfikowany kod do sortowania (na razie) można znaleźć pod adresem 'sorttable-TESTING-ONLY.js' z testową stroną html pod adresem 'TESTING-ONLY-sort_and_spin.htm'.

Tak, skrypt ustawia niektóre funkcje po załadowaniu strony ("....." oznacza linie pominięte):

makeSortable: function(table) {       //line 75 
    ...... 
    headrow = table.tHead.rows[0].cells; 

    for (var i=0; i<headrow.length; i++) {     //line 114 
    ..... 
    headrow[i].sorttable_sortfunction = sorttable.guessType(table,i); //line 126 

    // code to start/stop spinner 
    headrow[i].sorttable_spinner = (function(val) {  //line 136 
     return function(val) { 
     var $this = $(this), 
     data = $this.data(); 

     if (data.spinner) { 
      data.spinner.stop(); 
      delete data.spinner; 
     } 
     if (val > 0) { 
      var opts = { 
      ....... 
      }; 
      data.spinner = new Spinner($.extend({color: $this.css('color')}, opts)).spin(this); 
      // can see spinner added to DOM but does not display... 
     } 
    }})(i); 

Code je tworzy klikalny obsługi zdarzeń dla nagłówków kolumn:

headrow[i].sorttable_columnindex = i;       //line 171 
headrow[i].sorttable_tbody = table.tBodies[0]; 

dean_addEvent(headrow[i],"click", function(e) {     //line 176 
    .... does some stuff with class names, etc 

    this.sorttable_spinner(1); // set spinner on    //line 224 

    .... builds array to do sort then calls sort functions 
    if (sort_direction == 'forward') {       //line 247 
    row_array.sort(this.sorttable_sortfunction); 
    } else { 
    row_array.sort(this.sorttable_reversesortfunction); 
    } 

    tb = this.sorttable_tbody; 
    for (var j=0; j<row_array.length; j++) { 
    tb.appendChild(row_array[j][2]); 
    } 
    delete row_array; 

    this.sorttable_spinner(); // now stop the spinner   //line 261 

To wszystko wygląda na to, że powinno działać. W Firefoksie z firebugiem widzę DOM załadowany kodem spinnera, widzę, że obraca się on w przeglądarce, a linia, by wyłączyć spinner, usuwa go z DOM. ALE, jeśli nie jestem w trybie debugowania, tylko go uruchamia, to nie wyświetla się spinner? (debugowanie w IE10 nawet nie wyświetla spinnera).

Próbowałem .show() w różnych miejscach, ale zawsze otrzymuję powiadomienie o niedostępnej funkcji. Odwołanie do window.setTimeout(function() {... w celu oddzielnego procesu sortowania, ale nie można zrozumieć, jak zaimplementować to w tej sytuacji.

Jeśli ktoś mógłby mi podać kilka wskazówek, które byłyby bardzo cenne.

Pozdrowienia, Bryce S.

+1

przy okazji - nie mogę przejrzeć odpowiedzi na 5 dni jako poza zasięgiem internetu na wakacjach :-) – user1840734

+0

Pomyślałem, że zostawię notatkę tutaj, by sprawdzić moje [widelec stoisk] (http: // mottie .github.com/tablesorter/docs /). Próbowałem zrobić dla ciebie demo na jsFiddle, ale nie poradziłbym sobie z 3800 wierszami tabeli, ale na moim pulpicie odkryłem, że sortowanie trwało około 3 sekundy. Byłoby jeszcze szybciej, gdybyś nie używał widżetu zebr i nie stosował kolorowania wierszy za pomocą css ('tbody tr: nth-child (odd)'). – Mottie

+0

Witaj Mottie, dzięki za link do tego - szkoda, że ​​nie znalazłem tego kilka tygodni temu. Mój googleFoo mnie zawiódł. Będę naciskał na to, co mam teraz. Wiwaty, Bryce. – user1840734

Odpowiedz

7

Zasadniczo JavaScript ma jeden wątek na kodzie i interfejsie tylko razem. Oznacza to, że jeśli Twój kod nie zwalnia z kontroli, interfejs użytkownika nie zostanie wyświetlony, dopóki go nie wykonasz. Tak więc, tego rodzaju kodu:

spinner_on(); 
dostuff(); 
spinner_off(); 

co się dzieje, po włożeniu do wirowania do DOM, nie rzeczy, zdjąć pokrętła, zrezygnować z kontroli - i UI jest aktualizowana w końcu, bez pokrętła (bo w tej chwili , już nie istnieje).

Podstawowy wzór powinien być tak:

spinner_on(); 
setTimeout(function() { 
    dostuff(); 
    spinner_off(); 
}, 0); 

Działa to w następujący sposób: włóż tarczy do DOM, harmonogram czegoś zrezygnować z kontroli. Interfejs użytkownika jest aktualizowany (za pomocą pokrętła). Zaplanowane przebiegi funkcyjne: rzeczy robione, spinner zostaje usunięty z DOM, kontrola zostaje ponownie zrzeczona. Interfejs użytkownika jest aktualizowany (bez pokrętła).

Kiedy jesteś w debugerze, debugger rozpruwa kontrolę palcami kodu, dzięki czemu możesz zobaczyć swoją przędzarkę w interfejsie, gdy twój kod jest zawieszony.

+0

Cześć Amadan, to świetnie, teraz widzę spinnera. Dodano setTimeout() w funkcji dean_addEvent powyżej zaraz po uruchomieniu spinnera (linia 224), czyniąc resztę tego fragmentu kodu częścią wywołania setTimeout. Jednak widzę mój spinner, ale nie kręci się - jest statyczny z pierwszym wyświetlaczem. Czy jest coś, co mogę zrobić, żeby to naprawić? – user1840734

+0

Jak mogę ustawić coś, aby zamienić między kod i interfejs użytkownika, aby ekran się odświeżył. Lub jakoś działają dwa wątki ... – user1840734

+0

Jak już powiedziałem, JavaScript działa tylko w jednym wątku. (Właściwie możesz uzyskać więcej wątków za pomocą WebWorkers, ale nie mogą dotykać interfejsu użytkownika, więc nie możesz ich używać). Jedynym sposobem, aby twój kod zezwolił na odświeżenie ekranu, jest częstsze wstawianie 'setTimeout' - na przykład pozbyć się pętli i wykonać wywołanie kodu z 'setTimeout'. – Amadan

Powiązane problemy