2016-04-25 6 views
0

Ich habe eine Flexbox mit einer undefinierten Anzahl von Karten darin.Berechne Flexelementbreite vor dem Rendern mit JS

.box { 
    display: flex; 
    flex-wrap: wrap; 
} 

.card { 
    flex: 1 210px 
} 

Ich muss entscheiden, wie viele Karten in meiner Box setzen, zeigte die Anzahl der Karten wird die richtige Menge genau zwei Reihen zu füllen.

===== is a card 

--------------------- 
| ===== ===== ===== | 
| ===== ===== ===== | 
--------------------- 

Das bedeutet, dass bei einem .box von 630px, werde ich 6 Karten anzuzeigen. (630/210) * 2 = 6

Um die Karten-Nummer pro Zeile zu berechnen ich diesen Code bin mit:

getCardsPerRow() { 
    let listWidth = box.clientWidth 

    // use flex-basis width to compute the initial number of cards per row 
    let cardsNumber = Math.floor(listWidth/210) 

    // add to the cards width the left amount of available space (distributing it evenly) 
    let cardWidth = Math.floor(listWidth/cardsNumber + listWidth % cardsNumber) 

    // divide listWidth by the width of a single card to get the total 
    return Math.floor(listWidth/cardWidth) 
} 

Es funktioniert gut auf den meisten Situationen. Aber mit einigen Breiten bekomme ich eine falsche Nummer.

Zum Beispiel mit einem box breiten 1132px, erhalte ich 4, auch wenn Flexbox 5 Karten auf einer einzigen Zeile setzen.

Probieren Sie einen anderen Ansatz, wenn ich die Kartennummer tun Math.floor(listWidth/210), werde ich ein falsches Ergebnis mit (zum Beispiel) box Wide 1075px.
Es sollte 4 zurückgeben (gemäß dem flexbox CSS-Ergebnis), aber stattdessen gibt es 5 zurück.

Was mache ich falsch?

+0

Warum fügen Sie 'listWidth% cardsNumber' hinzu? Ich denke 'listWidth/cardsNumber' sollte ausreichen. –

+0

Ich habe es schon versucht (es ist der zweite Versuch in meinem Beitrag) –

+0

Umm, 'floor (1075/210)' ist 5. Habe ich etwas falsch verstanden? –

Antwort

0

Ihre Mathematik ist falsch, wie in den Kommentaren darauf hingewiesen. Lassen Sie sich durch sie gehen:

const listWidth = 1132; 
const cardsNumber = Math.floor(listWidth/210); 

An diesem Punkt cardsNumber 5 Offensichtlich gibt zusätzlichen Raum ist (von 5,3905.).

const cardWidth = Math.floor(listWidth/cardsNumber + listWidth % cardsNumber); 

Hier läuft alles schief. listWidth/cardsNumber ist 1132/5 oder 226.4. listWidth % cardsNumber oder 1132 % 5 ist 2.

Dies garantiert im Grunde, dass Sie einen cardWidth Wert berechnen werden, die entweder gleich ist (wenn listWidth % cardsNumber ist 0) oder etwas größer als die zur Verfügung stehende Breite. Beachten Sie, dass es mit 1130 gleich wäre.

Das andere Problem ist, wenn Dinge flex, was möglicherweise, warum Sie diese falsche Buchhaltung hinzugefügt haben. flex: 1 210px; bedeutet, dass beide Größen wachsen und schrumpfen können.

Was passiert, wenn eine Box 250px wird? Nun, 250 + 210 * 4 = 1090, so dass es immer noch paßt in 1132.

Was passiert, wenn alle Boxen 250px werden? Jetzt haben wir 1250, was zu groß ist. Jetzt haben wir nur 4 in der ersten Reihe.

Wie Sie sehen können, müssen Sie die minimale und maximale Breite der Boxen wissen, dass dies richtig zu berechnen. Wenn Sie sicher sind, dass sie alle auf 210px in Ordnung sein wird, dann nur cardsNumber verwenden und flex-grow auf 0

Ansonsten können Sie die Breiten der nächsten cardsNumber Boxen zusammenzufassen, und sehen, ob es weniger als listWidth. Ist dies nicht der Fall, hat diese Zeile eine Karte verloren (möglicherweise mehrere).)

Ein anderer Ansatz besteht darin, die Karten der Reihe nach einzeln hinzuzufügen und die offsetTop jedes einzelnen zu überprüfen. Wenn es zum zweiten Mal steigt, hast du die zweite Reihe gebrochen. Entfernen Sie das letzte hinzugefügte Element, und Sie haben zwei ordentlich gepackte Zeilen (so sauber wie Sie können.)

Verwandte Themen