come replicare il layout di stacking assoluto di pinterest.com [chiuso]


104

Sto cercando di replicare il layout div di Pinterest.com, in particolare il modo in cui il numero di colonne si regola per adattarsi di più / meno al ridimensionamento del browser e l'impilamento verticale non dipende dalle altezze delle colonne adiacenti. Il codice sorgente mostra che ogni div è posizione assoluta. Un co-fondatore ha risposto a un post di Quora affermando che è stato fatto con jQuery e CSS personalizzati. Vorrei che i risultati fossero ordinati da sinistra a destra. Qualsiasi direzione che potresti fornire per realizzarlo da solo sarebbe molto apprezzata.


Ho codificato il mio con semplici Jquery e CSS. Se vuoi che questo cambi al ridimensionamento, avvolgilo
Andrew WC Brown

Risposte:


79

Potresti anche controllare il jQuery Plug-in Masonry , per questo tipo di funzionalità.


3
Biblioteca davvero straordinaria. Ora lo sto usando senza problemi.
AhmetB - Google

183

Ho scritto lo script Pinterest. Gli ID non sono correlati al layout e vengono utilizzati per altri JS relativi all'interazione. Ecco la base di come funziona:

In anticipo:

  • Posizionare assolutamente i contenitori dei perni
  • Determina la larghezza della colonna
  • Determina il margine tra le colonne (la grondaia)

Imposta un array:

  • Ottieni la larghezza del contenitore genitore; calcolare il numero di colonne che si adatteranno
  • Crea un array vuoto, con una lunghezza uguale al numero di colonne. Usa questo array per memorizzare l'altezza di ogni colonna mentre costruisci il layout, ad esempio l'altezza della colonna 1 è memorizzata come array [0]

Fai scorrere ogni pin:

  • Metti ogni pin nella colonna più corta nel momento in cui viene aggiunto
  • "left:" === la colonna # (array dell'indice) moltiplicata per la larghezza della colonna + il margine
  • "top:" === Il valore nella matrice (altezza) per la colonna più corta in quel momento
  • Infine, aggiungi l'altezza del pin all'altezza della colonna (valore dell'array)

Il risultato è leggero. In Chrome, il layout di una pagina intera di oltre 50 pin richiede <10 ms.


4
Come intendi calcolare l'altezza della colonna? Come fai a sapere quanto dovrebbe essere alto se non conosci il numero e l'altezza degli oggetti al suo interno? C'è qualche possibilità che potresti impaginare qualche pseudo codice per dimostrare?
Michael Giovanni Pumo

22
ecco un solido tutorial - benholland.me/javascript/…
hollandben

1
Feedback da un utente anonimo (trovato nella coda di modifica): Curiosamente ho fatto esattamente lo stesso script in jQuery, con la leggera differenza di creare effettivamente una tabella con 1 riga e N colonne e aggiungerle alla colonna più corta da sinistra a destra priorità. Anche se ho anche aggiunto una costante "Differenza di altezza minima" necessaria per saltare effettivamente una colonna durante il posizionamento da sinistra a destra, questo dà al layout una visualizzazione cronologicamente intuitiva senza perdere le altezze il più uniforme possibile
oers

1
@MichaelGiovanniPumo Penso che l'altezza dovrebbe essere nota prima del layout (nel caso di Pinterest), non hanno uno stato "iniziale" in cui i div si sovrappongono. Questo non può essere fatto se l'altezza non è nota.
ptgamr

1
Il link di @ hollandben è morto, nuovo link: benholland.me/javascript/2012/02/20/…
Lukmo

57

Abbiamo rilasciato un plugin jQuery perché abbiamo ricevuto più volte la stessa domanda per Wookmark . Crea esattamente questo tipo di layout. Visualizzalo qui: plugin jQuery di Wookmark


4
Questa soluzione sembra caricarsi più velocemente della muratura
Michael L Watson

quale trovi di meglio? il wookmark o la muratura?
Ramje

Preferisco questo alla muratura, sembra più veloce come ha detto Michael.
nerdburn

2

Dopo aver esaminato tutte le opzioni, ho finito per implementare il layout simile a Pinterest in questo modo:

Tutti i DIV sono:

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

Questo li rende meglio posizionati nelle file rispetto a quando sono flottati.

Quindi, quando la pagina viene caricata, itero tutti i DIV in JavaScript per rimuovere gli spazi tra di loro. Funziona in modo accettabile quando:

  1. I DIV non sono molto diversi in altezza.
  2. Non ti dispiace alcune violazioni minori dell'ordine (alcuni elementi che erano sotto possono essere tirati su sopra).
  3. Non ti dispiace che la linea di fondo sia di altezza diversa.

Il vantaggio di questo approccio: il tuo HTML ha senso per i motori di ricerca, può funzionare con JavaScript disabilitato / bloccato dal firewall, la sequenza di elementi in HTML corrisponde alla sequenza logica (gli elementi più recenti prima del vecchio)


Ehi, potresti dirmi come hai calcolato l'offset che dovevi sottrarre? E anche come hai risolto il problema dell'ultimo elemento sul lato destro, perché c'è un elemento che è un po 'più grande e lo spinge lì.
Lukas Oppermann

@LukasOppermann 1) L'offset per la piastrella è la somma dell'offset per la piastrella nella stessa colonna nella riga precedente e la differenza tra l'altezza della piastrella più alta nella riga precedente e l'altezza della piastrella nella stessa colonna nella riga precedente. Dai un'occhiata a dev.sheeporpig.com/news (devi prima fare clic sul collegamento dev.sheeporpig.com/sheep/3210 per accedere al sito di sviluppo, in modo da poter vedere script non compressi e commentati in file separati), file di script stock_news.js, funzione compressTiles.
esp

@LukasOppermann 2) Se usi CSS come risposta (specialmente display: inline-block) non succede. Succede solo se fluttui: lasci i tuoi div. Non uso il float.
esp

0

Suddividono le entità per colonne con ID (soluzione sbagliata ... è meglio usare i nomi delle classi) e quindi calcolano le posizioni per gruppi di colonne


2
+1 Per dare un'occhiata al loro codice sorgente.
Bojangles

È stato interessante per me, ma penso che ci sia una soluzione
migliore

Potresti usare display: inline-blocksuppongo, ma elementi di diversa altezza verticale non starebbero insieme.
Bojangles

1
meglio usare contenitori di colonne (div con float:left;e l'ultimo con overflow: hidden;) e memorizzare gli elementi lì
ant_Ti

4
Buon punto. Se davvero volessi seguire il percorso JavaScript, potresti usare jQuery Masonry?
Bojangles


0

Potresti usare float e dimensionare le larghezze div utilizzando percentuali insieme a min-width per forzare la caduta automatica dei div una volta raggiunta la larghezza minima? È il modo in cui lo abbiamo fatto funzionare su http://www.goldtree.co.za/work

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.