2013-01-09 13 views
7

Ho eseguito un problema cercando di avere una "finestra di caricamento" sulla mia pagina che viene eseguita mentre una tabella viene ordinata, in particolare per i client più lenti, poiché possono essere necessari fino a 10 secondi per ordina la pagina. Posso vedere il DOM viene modificato con il codice spinner, tuttavia non viene visualizzato. Speravo che ci potesse essere qualcosa che potrei fare per forzare questa visualizzazione di spinner prima che accadesse il genere, e naturalmente interromperlo quando l'ordinamento è completato.jQuery: visualizzazione forzata dom modificata

Il mio ordinamento è basato su 'sorttable.js' che ho modificato per gestire un ordinamento secondario sulla prima colonna della tabella (con i nomi in esso).

La mia trottola utilizza 'spin.js'.

Sono ancora un novizio con questo materiale jQuery, e questo codice selezionabile è piuttosto coinvolto. Metto in evidenza le parti sottostanti, ma il mio codice di ordinamento completo modificato (per ora) può essere trovato al numero 'sorttable-TESTING-ONLY.js' con una pagina html di prova allo 'TESTING-ONLY-sort_and_spin.htm'.

Quindi, script imposta alcune funzioni quando caricamento della pagina ("....." significa linee saltati):

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); 

Codice li crea un gestore di eventi cliccabile per le intestazioni delle colonne:

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 

Sembra che tutto dovrebbe funzionare. In Firefox con firebug vedo che il DOM viene caricato con il codice spinner, lo vedo ruotare nel browser, e la linea per disattivare lo spinner lo rimuove dal DOM. MA, se non sono in modalità di debug, solo eseguendolo, quindi non viene visualizzato nessuno spinner? (il debugging con IE10 non visualizza nemmeno lo spinner).

Ho provato .show() in vari punti ma mi viene sempre detto che non è una funzione disponibile. Ho visto un riferimento a window.setTimeout(function() {... per fornire un processo separato per l'ordinamento, ma non ho potuto capire come implementarlo in questa situazione.

Se qualcuno potesse darmi qualche suggerimento che sarebbe molto apprezzato.

saluti, Bryce S.

+1

a proposito - non è possibile rivedere le risposte per 5 giorni come fuori dalla portata di Internet in vacanza :-) – user1840734

+0

Ho pensato di lasciare una nota qui per controllare la mia [fork of tablesorter] (http: // mottie .github.com/tablesorter/docs /). Ho provato a creare una demo per te su jsFiddle, ma non è stato in grado di gestire le righe del tavolo 3800+, ma sul mio desktop ho scoperto che un ordinamento richiedeva circa 3 secondi. Sarebbe ancora più veloce se non si usa il widget zebra e si applica la colorazione delle righe usando css ('tbody tr: nth-child (dispari)'). – Mottie

+0

Ciao Mottie, grazie per il link a questo - Vorrei averlo trovato un paio di settimane fa. Il mio googleFoo mi ha deluso. Continuerò con quello che ho adesso. Saluti, Bryce. – user1840734

risposta

7

In sostanza, JavaScript ha un solo filo per il codice e interfaccia utente insieme. Ciò significa che se il tuo codice non rinuncia al controllo, l'interfaccia utente non viene mostrata fino a quando non lo fai. Quindi, in questa sorta di codice:

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

ciò che accade è, è inserto filatore in DOM, fare cose, rimuovere filatore, cedere il controllo - e interfaccia utente è aggiornato alla fine, senza ogiva (perché, in questo momento , non esiste più).

Il modello di base dovrebbe essere questo:

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

Questo funziona come segue: inserire filatore in DOM, calendario qualcosa, cedere il controllo. L'interfaccia utente viene aggiornata (con lo spinner). Esecuzioni di funzioni pianificate: le operazioni vengono eseguite, lo spinner viene rimosso dal DOM, il controllo viene nuovamente rilasciato. L'interfaccia utente viene aggiornata (senza lo spinner).

Quando sei in un debugger, il debugger strappa il controllo dalle dita del tuo codice, in modo che tu possa vedere lo spinner nell'interfaccia utente mentre il codice è in pausa.

+0

Ciao Amadan, è grandioso, ora posso vedere lo spinner. Aggiunto setTimeout() nella funzione dean_addEvent sopra appena dopo aver avviato lo spinner (riga 224) rendendo il resto di quel pezzo di codice parte della chiamata setTimeout. Tuttavia, vedo il mio spinner ma non gira: è statico con il primo display. C'è qualcosa che posso fare per risolverlo? – user1840734

+0

Come posso impostare qualcosa da scambiare tra il codice e l'interfaccia utente in modo che lo schermo si aggiorni. O avere due thread in esecuzione in qualche modo ... – user1840734

+0

Come ho detto, JavaScript viene eseguito solo in un thread. (In realtà, puoi ottenere più discussioni con i WebWorkers, ma non possono toccare l'interfaccia utente, quindi non puoi usarli.) L'unico modo per far sì che il tuo codice consenta l'aggiornamento dello schermo è se inserisci un 'setTimeout' più spesso - per esempio, sbarazzati del tuo loop e fai in modo che il codice si chiami da solo con 'setTimeout'. – Amadan