2009-11-08 5 views
5

Ho un set di dati relativamente grande di elementi (poche migliaia di elementi) che voglio navigare applicando un numero di filtri lato client in un'applicazione web. L'applicazione della logica di filtraggio non è un problema, la domanda riguarda quale metodo utilizzare per aggiornare la tabella dei risultati corrispondenti per ottenere la migliore esperienza utente. I metodi che ho trovato sono:Le migliori pratiche per filtrare gli elementi sul lato client con JavaScript, nascondere o rimuovere dal DOM?

  1. Impostazione della classe di ogni riga da nascondere o mostrare (utilizzando la visibilità: compresso per nasconderla) e mantenendo l'elemento DOM nella tabella.
  2. Mantenere un elemento DOM per ogni elemento di dati, scollegarlo/collegarlo alla tabella per nasconderlo e mostrarlo.
  3. Basta tenere un oggetto astratto per ogni elemento di dati, creando un oggetto DOM su richiesta per mostrarlo.

Quale è la migliore esperienza utente? Qualche altro metodo consigliato oltre a quelli che ho elencato già?

risposta

2

Se l'area di visualizzazione ha dimensioni fisse (o almeno una dimensione massima), e tu deve filtrare sul lato client, vorrei non creare un nodo DOM per ciascun elemento, ma invece riutilizzare un set predefinito di nodi DOM come modelli, nascondendo i modelli non necessari a seconda del numero di risultati dal filtro. Ciò ridurrà drasticamente i nodi DOM nel documento che manterrà la tua pagina reattiva ed è abbastanza facile da implementare.

Esempio HTML *:

<ul id="massive-dataset-list-display"> 
    <li> 
     <div class="field-1"></div> 
     <div class="field-2"></div> 
     <div class="field-n"></div> 
    </li> 
    <li> 
     <div class="field-1"></div> 
     <div class="field-2"></div> 
     <div class="field-n"></div> 
    </li> 
    <li> 
     <div class="field-1"></div> 
     <div class="field-2"></div> 
     <div class="field-n"></div> 
    </li> 
    . 
    . 
    . 
</ul> 

Esempio JavaScript *:

var MassiveDataset = function(src) { 
    var data   = this.fetchDataFromSource(src); 
    var templateNodes = $("#massive-dataset-list-display li"); 

    // It seems that you already have this handled, but just for 
    // completeness' sake 
    this.filterBy(someParam) { 
     var filteredData = []; 
     // magic filtering of `data` 
     this.displayResults(filteredData); 
    }; 

    this.displayResults(filteredData) { 
     var resultCount = filteredData.length; 

     templateNodes.each(function(index, node) { 
      // There are more results than display node templates, start hiding 
      if (index >= resultCount) { 
       $(node).hide(); 
       return; 
      } 

      $(node).show(); 
      this.formatDisplayResultNode(node, filteredData[i]); 
     }); 
    }; 

    this.formatDisplayResultNode = function(node, rowData) { 
     // For great justice 
    }; 
}; 

var md = new MassiveDataset("some/data/source"); 
md.filterBy("i can haz filter?"); 

* Non testato. Non aspettarti che copia/incolla funzioni, ma sarebbe bello.

+0

Questa è una buona idea. Potrei finire usando la navigazione basata sulla pagina lato client per mantenere la dimensione della pagina (visiva) verso il basso, che mi darà un limite superiore gestibile per il numero di elementi visibili. – SoftMemes

0

mi rendo conto che non è esattamente quello che stai chiedendo, ma da quando hai aperto la porta per i supplenti ...

Avete preso in considerazione di fare qualsiasi server-side di filtraggio? È possibile caricare i risultati con AJAX se l'utente modifica le opzioni di filtro e in questo modo non si caricano migliaia di righe di dati in un browser quando è possibile visualizzarne solo una parte. Potrà potenzialmente salvare te e la larghezza di banda del visitatore, anche se questo dipenderà da come il tuo sito viene veramente utilizzato.

In sostanza, se si decide in anticipo quali dati si desidera mostrare, non è necessario passare attraverso la difficoltà di scegliere cosa c'è.

Capisco che questo potrebbe non essere adatto alle vostre esigenze, ma lo offro come suggerimento nel caso in cui foste bloccati dall'idea del lato client.

+0

Non ho chiuso la porta a fare cose serveride completamente, ho intenzione di valutare la soluzione lato client prima e vedere se funziona, grazie per il commento. – SoftMemes

0

La manipolazione del DOM è troppo lenta per "poche migliaia di voci". Supponendo che tu abbia davvero una buona ragione per cui non stai ricevendo il server per fare il filtraggio, la soluzione migliore che ho trovato è quella di utilizzare le trasformazioni XSL lato client su dati conservati come XML.

Le trasformazioni stesse sono molto veloci anche su serie di dati ragionevolmente grandi. Alla fine assegnerai i risultati alla proprietà innerHTML di un DIV contenente dove vuoi che appaia la tabella. L'uso di innerHTML per grandi cambiamenti nel DOM è molto più rapido della manipolazione del DOM con Javascript.

Edit: Risposte alle osservazioni di Justin Johnson: -

Se il set di dati è che di grandi dimensioni, l'XML è potenzialmente sarà bestiale di grandi dimensioni.

Nota Ho già effettuato la dichiarazione di non responsabilità nel mio primo paragrafo riguardante l'arruolamento dei server. Potrebbe esserci un caso qui per cambiare il design e fare un uso ragionevole di AJAX, o semplicemente non tentare di mostrare molti dati contemporaneamente. Tuttavia sto facendo del mio meglio per rispondere alla domanda posta.

Vale anche la pena considerare che "beastly large" è almeno una funzione della larghezza di banda. In una web application intranet ben collegata la larghezza di banda non è così elevata. Inoltre ho visto e utilizzato implementazioni che creano e riutilizzano l'XML memorizzato nella cache nel tempo.

Inoltre, se XML viene convertito in un oggetto DOM, come va meglio?

C'è una grande differenza tra la tecnica che propongo e la manipolazione DOM diretta da Javascript. Considerare quando il codice in javascript modifica il DOM il motore sottostante non ha modo di sapere che altre modifiche stanno per essere seguite immediatamente, né può essere sicuro che il javascript non esaminerà immediatamente altre proprietà del DOM. Quindi, quando viene apportata una modifica al DOM tramite Javascript, il browser deve assicurarsi di aggiornare tutti i tipi di altre proprietà in modo che siano coerenti con un rendering completato.

Tuttavia, quando innerHTML viene assegnato una stringa HTML di grandi dimensioni, il browser può creare tranquillamente un intero gruppo di oggetti DOM senza eseguire alcun ricalcolo, può rinviare un aggiornamento di zillion a vari valori di proprietà fino a quando non viene creato l'intero DOM. Quindi per i cambiamenti su larga scala l'innerHTML soffierà la manipolazione diretta del DOM fuori dall'acqua.

+0

Se il set di dati è così grande, l'XML potrebbe essere potenzialmente bestiale. Inoltre, se XML viene convertito in un oggetto DOM, come è meglio? –

1

L'aggiunta di una classe e l'utilizzo di CSS per mostrare/nascondere l'elemento sarà probabilmente la più veloce (capacità di codifica e prestazioni), specialmente con così tanti elementi.

Se si desidera utilizzare il percorso di manipolazione DOM, è consigliabile modificare il DOM offline. Memorizza nella cache l'albero DOM in memoria (una variabile locale), aggiorna tutte le righe e sostituisci il nodo DOM originale. Vedere http://www.peachpit.com/articles/article.aspx?p=31567&seqNum=5 per ulteriori informazioni su questo argomento.


ho fatto un progetto che ha richiesto gli elementi di filtraggio sulla posizione all'interno di 'finestra' a Google Maps e un cursore del valore min-max (per coloro che sono curiosi, era per un sito web immobiliare).

La prima versione utilizzava una richiesta AJAX per ottenere tutti gli elementi filtrati (lato server), quindi ogni modifica nel filtro richiedeva nuovi dati. Quindi i dati JSON sono stati analizzati ai nodi DOM e aggiunti al documento. Inoltre, in questo caso l'indicizzazione dei motori di ricerca degli articoli non era possibile.

La seconda versione utilizzava anche una richiesta AJAX, ma questa volta richiedeva solo gli ID filtrati degli articoli. Tutti gli elementi erano presenti nell'HTML con gli ID univoci e gli oggetti filtrati avevano un nome di classe extra per nasconderli inizialmente. Ogni volta che il filtro cambiava, venivano richiesti solo gli ID filtrati e il nome della classe dell'elemento veniva aggiornato di conseguenza. Questo ha migliorato significativamente la velocità, specialmente in Internet Explorer (che ha il motore JavaScript più lento - dei nostri browser supportati -!) ...

+0

Sto effettivamente facendo anche il filtraggio di viewport di Google Maps e non ho deciso se sto per fare il lato client di filtraggio o usare AJAX. È interessante sapere di quest'ultima tecnica, forse ottenere il meglio da entrambi i mondi. – SoftMemes

+0

Solo il filtro di Google Maps è fatto lato client, perché non volevamo fare il filtraggio di geolocalizzazione sul server (ma è ovviamente possibile). Inoltre, se l'utente non ha JavaScript (attivato), Google Maps e il filtro sul lato client non funzioneranno comunque ... – Ronald

Problemi correlati