2013-04-21 8 views
12

Mam kilka DIV z treścią, które mają atrybut wagi danych, który jest regularnie aktualizowany za pośrednictwem AJAX.Ponowne rozmieszczanie/zapisywanie DIV bez ponownego wstawiania do DOM

Sortuję je w pętli, w której sprawdzam nowe wartości pochodzące z żądania ajax.

Ponieważ waga danych może być aktualizowana w dowolnej chwili do dowolnej wartości, zamówienie może się całkowicie zmienić z aktualizacji na aktualizację.

Moja logika sortowania wydaje się błędna (co najmniej;)), ponieważ porównuje tylko każdy element z następnym poprzez .next(), więc musisz kliknąć "Sortuj według danych" waga "max. 4 razy dla 4 elementów, dopóki nie zostaną posortowane (patrz skrzypce poniżej)

Ważne jest, aby wiedzieć, że DIV, które mają być sortowane, zawierają źródła zewnętrzne, takie jak obrazy, wideo itp., Więc ważne jest, aby były przenoszone i nie były ponownie tworzone, ponieważ myślę, że po ponownym wstawieniu do DOM, zawarte ressources są ponownie ładowane, co jest niedopuszczalne dla mojego przypadku użycia.

Jak trudno descripte i może zrozumieć, tutaj jest moje skrzypce:

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

Aktualizacja

Choć główny problem jest rozwiązany, nadal istnieje problem, że gdy F. E. Youtube-Video są dołączone, są ponownie ładowane za każdym razem, gdy DIV są ponownie zamieniane, nawet jeśli wideo nie zmienia miejsca w DOM. Że a) wygląda dziwnie i b) przerywa wideo-grę. Czytając więcej na ten temat, przenoszenie elementów iframe w DOM zawsze sprawia, że ​​przeładowują swoje treści - jak głupio to jest?

Fiddle jest aktualizowany o stałą masę danych 1 dla wideo YT, dzięki czemu zawsze pozostaje na wierzchu.

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

pomysły mile widziane !!

Odpowiedz

14

Oto pierwszy sposób, który przyszedł do głowy:

$("#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); 
    }); 
}); 

wydaje się działać: http://jsfiddle.net/PdGTK/6/

Zasadniczo co to robi jest stworzenie obiektu jQuery ($articles), który zawiera wszystkie artykuły. Następnie sortuje elementy w obiekcie jQuery zgodnie z ich atrybutem data-weight. Następnie przechodzi przez nie w nowej kolejności i dołącza je do opakowania - zauważając, że gdy już znajdziesz się w DOM, zostanie on przeniesiony.

+0

Na koniec, dlaczego nie zrobisz '$ wrapper.append ($ articles)'? –

+0

@AlessandroVendruscolo - Ponieważ nie jestem mądry. (Zobacz także pierwsze zdanie mojej odpowiedzi.) Ale tak, to powinno zadziałać. – nnnnnn

+0

dziękuję! To wygląda dobrze. Jeśli użyję sugestii @AlessandroVendruscolo, czy nie zaszkodzi mi to, że trzeba je przenieść, a nie ponownie włożyć? –

5

ten sposób można go rozwiązać:

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

twoje skrzypce nie działają dla mnie, ale lorempixel jest świetny wiedzieć o. Dzięki! –

+0

Co masz na myśli, że to nie działa, czy nie sortuje artykułów według wagi danych? – dfsq

+0

dokładnie, na moim komputerze (OSX/safari) nie sortuje. –

1

muszę też zmienić kolejność elementów bez konieczności ponownego wkładania do DOM. Możesz to zrobić, modyfikując właściwość CSS.

Na zewnętrznej własności pojemnik zestaw CSS:

display: flex; 
flex-direction: column; 

i dla każdego zestawu elementów:

order: X; 

gdzie X rośnie w porządku rosnącym.

+0

to dobry pomysł, a do zmiany aranżacji wystarczy ustawić kolejność nowy –

Powiązane problemy