2013-04-21 10 views
12

Ho diversi DIV con contenuto che hanno un attributo peso-dati che viene aggiornato regolarmente tramite AJAX.Re-arranging/-sorting DIVs senza re-inserimento in DOM

I li ordinano nel ciclo in cui I itate sui nuovi valori provenienti dalla richiesta Ajax.

Poiché il peso dei dati può essere aggiornato in qualsiasi momento a qualsiasi valore, l'ordine può cambiare completamente da aggiornamento ad aggiornamento.

La mia logica di ordinamento sembra imperfetta (per non dire altro;)) perché confronta solo ogni elemento con il successivo tramite .next() quindi è necessario fare clic su "Ordina per peso dei dati" max. 4 volte per 4 elementi fino a quando non sono ordinati (vedere il violino sotto)

È importante sapere che i DIV da ordinare contengono risorse esterne come immagini, video ecc. Quindi è importante che vengano spostati e non ricreati, perché penso che quando reinseriti nel DOM, le risorse contenute vengano ricaricate, il che è inaccettabile per il mio caso d'uso.

Come è difficile descripte e forse capire, qui è il mio violino:

http://jsfiddle.net/PdGTK/5/

Aggiornamento

Mentre il problema principale è risolto, c'è ancora il problema che quando f.e. I video di YouTube sono inclusi, vengono ricaricati ogni volta che i DIV vengono riordinati, anche se il video non cambia posto nel DOM. Che a) sembra strano eb) interrompe il video-play. Leggendo di più sull'argomento, spostare gli iframe nel DOM sembra sempre farli ricaricare il loro contenuto - quanto è stupido?

Fiddle viene aggiornato con un peso fisso di 1 per YT-video, quindi rimane sempre in primo piano.

http://jsfiddle.net/PdGTK/10/

idee molto benvenuto !!

risposta

14

Ecco il primo modo in cui è venuto in mente:

$("#sortButton").on("click", function() { 
    var $wrapper = $('#wrapper'), 
     $articles = $wrapper.find('.article'); 
    [].sort.call($articles, function(a,b) { 
     return +$(a).attr('data-weight') - +$(b).attr('data-weight'); 
    }); 
    $articles.each(function(){ 
     $wrapper.append(this); 
    }); 
}); 

sembra funzionare: http://jsfiddle.net/PdGTK/6/

Fondamentalmente quello che sta facendo è la creazione di un oggetto jQuery ($articles) che contiene tutti gli articoli. Quindi ordina gli elementi nell'oggetto jQuery in base all'attributo data-weight. Quindi li segue nel nuovo ordine e li aggiunge al wrapper - notando che quando si sposta .append() un elemento già presente nel DOM.

+0

Alla fine, perché non fai '$ wrapper.append ($ articoli)'? –

+0

@AlessandroVendruscolo - Perché non sono intelligente. (Vedi anche la frase di apertura della mia risposta.) Ma sì, dovrebbe funzionare. – nnnnnn

+0

grazie! Sembra bello. Se utilizzo il suggerimento di @AlessandroVendruscolo, non mi ferirebbe il fatto che debbano essere spostati piuttosto che reinseriti? –

5

Questo è come si può risolvere la cosa:

var $wrapper = $('#wrapper'), 
    $art = $wrapper.children('.article'); 

$art.sort(function(a, b) { 
    return +$(a).data('weight') - +$(b).data('weight'); 
}) 
.each(function() { 
    $wrapper.append(this); 
}); 

http://jsfiddle.net/dfsq/PdGTK/8/

+0

il tuo violino non funziona per me, ma il lorempixel è ottimo sapere. Grazie! –

+0

Cosa vuoi dire che non funziona, non ordina gli articoli in base al peso dei dati? – dfsq

+0

esattamente, sulla mia macchina (OSX/safari) non ordina. –

1

ho bisogno di troppo elementi riordinare senza re-inserimento nel DOM. Puoi farlo modificando la proprietà CSS.

Per proprietà contenitore insieme CSS esterno:

display: flex; 
flex-direction: column; 

e per ogni insieme elemento:

order: X; 

dove X crescente in ordine crescente.

+0

questa è una buona idea e per ri-organizzare basta impostare l'ordine nuovo –

Problemi correlati