jak powielić absolutny układ div z pinterest.com [zamknięte]

104

Chcę odtworzyć układ div Pinterest.com, a konkretnie sposób, w jaki liczba kolumn dostosowuje się, aby dopasować mniej / więcej do zmiany rozmiaru przeglądarki, a układanie w pionie nie zależy od wysokości sąsiednich kolumn. Kod źródłowy pokazuje, że każdy element div jest pozycją bezwzględną. Współzałożyciel odpowiedział na post Quora, w którym stwierdził, że jest to zrobione z niestandardowym jQuery i CSS. Chciałbym, aby wyniki były posortowane od lewej do prawej. Wszelkie wskazówki, które mógłbyś podać, aby to zrobić sam, byłyby bardzo mile widziane.

chrickso
źródło
Zakodowałem własne za pomocą prostego JQuery i CSS. Jeśli chcesz to zmienić przy zmianie rozmiaru, po prostu zawiń ją w funkcję i obserwuj zmianę rozmiaru w elemencie kontenera jsfiddle.net/92gxyugb/1
Andrew WC Brown

Odpowiedzi:

79

Możesz również sprawdzić jQuery Plug-in Masonry , pod kątem tego rodzaju funkcjonalności.

Pion.
źródło
3
Naprawdę niesamowita biblioteka. Teraz używam go bez żadnych problemów.
AhmetB - Google
183

Napisałem skrypt na Pinterest. Identyfikatory nie są powiązane z układem i są używane dla innych JS związanych z interakcjami. Oto podstawa tego, jak to działa:

Uprzednio:

  • Absolutnie ustaw pojemniki na szpilki
  • Określ szerokość kolumny
  • Określ margines między kolumnami (rynna)

Skonfiguruj macierz:

  • Uzyskaj szerokość kontenera nadrzędnego; oblicz liczbę pasujących kolumn
  • Utwórz pustą tablicę o długości równej liczbie kolumn. Użyj tej tablicy do przechowywania wysokości każdej kolumny podczas tworzenia układu, np. Wysokość kolumny 1 jest przechowywana jako tablica [0]

Zapętlaj przez każdy pin:

  • Umieść każdy pin w najkrótszej kolumnie w momencie dodania
  • "left:" === numer kolumny (tablica indeksu) razy szerokość kolumny + margines
  • "top:" === Wartość w tablicy (wysokość) dla najkrótszej kolumny w tym czasie
  • Na koniec dodaj wysokość szpilki do wysokości kolumny (wartość tablicy)

Rezultat jest lekki. W przeglądarce Chrome ułożenie całej strony zawierającej ponad 50 pinów zajmuje mniej niż 10 ms.

Evan Sharp
źródło
4
Jak masz na myśli obliczyć wysokość kolumny? Skąd wiesz, jaka powinna być wysokość, jeśli nie znasz liczby i wysokości znajdujących się w nim elementów? Jest jakaś szansa, że ​​mógłbyś stworzyć pseudokod, aby zademonstrować?
Michael Giovanni Pumo
22
tutaj jest solidny samouczek - benholland.me/javascript/ ...
hollandben
1
Informacje zwrotne od anonimowego użytkownika (znalezione w kolejce edycji): Co ciekawe, zrobiłem dokładnie ten sam skrypt w jQuery, z niewielką różnicą, że faktycznie utworzyłem tabelę z 1 wierszem i N kolumnami i po prostu dołączyłem je do najkrótszej kolumny od lewej do prawej priorytet. Mimo że dodałem również stałą „Minimalna różnica wysokości” wymagana do faktycznego pominięcia kolumny podczas pozycjonowania od lewej do prawej, zapewnia to układowi chronologicznie intuicyjny wyświetlacz bez utraty wysokości, która jest tak równa, jak to możliwe
oferuje
1
@MichaelGiovanniPumo Myślę, że wysokość powinna być znana przed układem (w przypadku Pinteresta), nie mają one stanu „początkowego”, w którym elementy div nakładają się na siebie. Nie można tego zrobić, jeśli wysokość nie jest znana.
ptgamr,
1
Link do @ hollandben jest martwy, nowy link: benholland.me/javascript/2012/02/20/…
Lukmo
57

Wypuściliśmy wtyczkę jQuery, ponieważ otrzymaliśmy to samo pytanie kilka razy dla Wookmark . Tworzy dokładnie taki układ. Zobacz to tutaj - wtyczka Wookmark jQuery

GBKS
źródło
4
To rozwiązanie wydaje się ładować szybciej niż murarstwo
Michael L Watson
co uważasz za lepsze? Wookmark czy mur?
Ramje
Wolę to od muru, wydaje się szybsze, jak powiedział Michael.
nerdburn,
2

Po przejrzeniu wszystkich opcji ostatecznie zaimplementowałem układ podobny do Pinteresta w następujący sposób:

Wszystkie DIV to:

div.tile {
    display: inline-block;
    vertical-align: top;
}

To sprawia, że ​​układają się w rzędach lepiej niż gdy są pływające.

Następnie po załadowaniu strony iteruję wszystkie DIV w JavaScript, aby usunąć przerwy między nimi. Działa zadowalająco dobrze, gdy:

  1. DIV nie różnią się zbytnio wysokością.
  2. Nie masz nic przeciwko drobnym naruszeniom kolejności (niektóre elementy, które były poniżej, można podciągnąć powyżej).
  3. Nie przeszkadza ci to, że dolna linia ma różną wysokość.

Zaleta tego podejścia - Twój HTML ma sens dla wyszukiwarek, może działać z JavaScript wyłączonym / zablokowanym przez zaporę ogniową, sekwencja elementów w HTML jest zgodna z sekwencją logiczną (nowsze elementy przed starszymi)

zwł
źródło
Hej, czy możesz mi powiedzieć, jak obliczyłeś przesunięcie, które musiałeś odjąć? A także, jak rozwiązałeś problem z tym, że ostatni element znajduje się po prawej stronie, ponieważ jest jeden element, który jest trochę większy i popycha go tam.
Lukas Oppermann
@LukasOppermann 1) Przesunięcie płytki to suma przesunięcia płytki w tej samej kolumnie w poprzednim wierszu i różnicy między wysokością najwyższej płytki w poprzednim wierszu a wysokością płytki w tej samej kolumnie w poprzednim rzędzie. Zajrzyj na dev.sheeporpig.com/news (najpierw musisz kliknąć link dev.sheeporpig.com/sheep/3210, aby uzyskać dostęp do witryny programistycznej - dzięki czemu możesz zobaczyć nieskompresowane i skomentowane skrypty w osobnych plikach), plik skryptu stock_news.js, funkcja compressTiles.
szczególnie
@LukasOppermann 2) Jeśli używasz CSS jako odpowiedzi (zwłaszcza display: inline-block), to się nie dzieje. Dzieje się tak tylko wtedy, gdy pływasz: opuściłeś swoje elementy div. Nie używam pływaka.
szczególnie
0

Dzielą jednostki według kolumn z identyfikatorami (złe rozwiązanie ... lepiej używaj nazw klas), a następnie obliczają pozycje według grup kolumn

ant_Ti
źródło
2
+1 za przejrzenie ich kodu źródłowego.
Bojangles
To było dla mnie interesujące, ale myślę, że jest lepsze rozwiązanie z mniejszą
liczbą
display: inline-blockPrzypuszczam, że można by użyć , ale przedmioty o różnej wysokości w pionie nie będą siedzieć razem.
Bojangles
1
lepiej używać kontenerów kolumn (div z float:left;i ostatni z overflow: hidden;) i przechowywać tam elementy
ant_Ti
4
Słuszna uwaga. Jeśli naprawdę chcesz skorzystać z trasy JavaScript, możesz użyć jQuery Masonry?
Bojangles
0

Możesz użyć elementów zmiennoprzecinkowych i zmienić szerokość elementów div, używając wartości procentowych razem z min-szerokością, aby wymusić automatyczne opadanie elementów div po osiągnięciu minimalnej szerokości? Tak to działa w witrynie http://www.goldtree.co.za/work

Jestem Goldtree
źródło