2013-07-08 10 views
10

Korzystanie z muru na stronie katalogu. Domyślnie wyświetlane elementy sortują według daty, a następnie według numeru części. Moje obrazy mają różną wysokość. Problem polega na tym, i popraw mnie, jeśli się mylę, Masonry ustawia wiersz 2, pozycja 1 poniżej najkrótszej pozycji w rzędzie 1, a nie po lewej stronie. Innymi słowy, kiedy moja baza danych zwraca określoną kolejność, Masoner umieszcza te elementy uporządkowane od góry do dołu (przy różnych wysokościach), zamiast od lewej do prawej.jQuery Kamieniarstwo sortowanie od lewej do prawej zamiast od góry do dołu?

Nie znajduję niczego w dokumentacji, aby to kontrolować. Czy istnieje sposób zmuszenia Kamieniarza do utrzymywania przedmiotów w kolejności od lewej do prawej i po prostu unoszą się pionowo w zależności od wzrostu?

Próbowałem opublikować ilustrację, ale najwyraźniej nie jestem do tego upoważniony. Oto link do ilustracji:

enter image description here

+0

Problem będziesz mieć to, że 1 duża komórka może być tak wysoki jak 2 mniejszych komórek (lub więcej). W takim przypadku jedna komórka będzie obejmować 2 lub więcej wierszy, co może być bardzo mylące. Na przykład, jeśli weźmiesz drugą ilustrację i zredukujesz ją do 3 kolumn, będziesz układać pola 3, 6 i 9, które są wysokie. W efekcie otrzymasz pudełko 7 przed 6, a będziesz kontynuować przesuwanie, jeśli masz więcej pudeł. Jeśli nie zmienisz pionowych marginesów, aby wyrównać pola, nie rozumiem, jak można to zrobić. – Tchoupi

Odpowiedz

0

Prosta odpowiedź brzmi „nie”

murarskie niemal z definicji przestawia rzeczy w montażu i zakłada, że ​​kolejność nie jest ważna. Mówię "prawie", ponieważ uważam, że masz rację, że nie jest to nigdzie napisane w dokumentach - ale tak to działa.

3

Nie ma opcji w Masonry do sortowania przedmiotów, ponieważ jest to prosta wtyczka, która umieszcza cegły jeden po drugim. Wybór nowej pozycji cegły jest prosty: umieść go wyżej, jak możesz.

Ale w tym przypadku można zmienić skrypt, dodając dwie linie definiujące sortowanie, zakładając, że wszystkie cegły mają taką samą szerokość (na przykład zawsze 5 w rzędzie).

Aby to zademonstrować użyłem jQuery Masonry (został skompresowany) i można go sprawdzić w this Fiddle.

JS

$.Mason.prototype._placeBrick = function(e) { 
    var n = $(e), 
     r, i, s, o, u; 
    r = Math.ceil(n.outerWidth(!0)/this.columnWidth), r = Math.min(r, this.cols); 
    if (r === 1) s = this.colYs; 
    else { 
     i = this.cols + 1 - r, s = []; 
     for (u = 0; u < i; u++) o = this.colYs.slice(u, u + r), s[u] = Math.max.apply(Math, o) 
    } 
    var a = Math.min.apply(Math, s), 
     f = 0; 
    for (var l = 0, c = s.length; l < c; l++) 
     if (s[l] === a) { 
      f = l; 
      break 
     } 
    /* Add new calculation, what column next brick is in: */ 
    f = $(e).index() % this.cols; /* Get col index f: Just divide with element's index */ 
    a = s[f]; /* This is current height for f-th column */ 
    /* END of customizing */ 
    var h = { 
     top: a + this.offset.y 
    }; 
    h[this.horizontalDirection] = this.columnWidth * f + this.offset.x, this.styleQueue.push({ 
     $el: n, 
     style: h 
    }); 
    var p = a + n.outerHeight(!0), 
     d = this.cols + 1 - c; 
    for (l = 0; l < d; l++) this.colYs[f + l] = p; 
}; 
0

Zainspirowany skobaljic's answer (który jest kompatybilny tylko z Gilotyny v2), mam posiekany v3 do zrobienia tego samego. Oto ona:

Masonry.prototype._getItemLayoutPosition = function(item) { // Hack Masonry to order items by their order in the DOM 
    item.getSize(); 
    // how many columns does this brick span 
    var remainder = item.size.outerWidth % this.columnWidth; 
    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 
    // round if off by 1 pixel, otherwise use ceil 
    var colSpan = Math[ mathMethod ](item.size.outerWidth/this.columnWidth); 
    colSpan = Math.min(colSpan, this.cols); 

    var col = $(item.element).index() % 3; // HACK : determine which column we want based on the element's index in the DOM 

    var colGroup = this._getColGroup(colSpan); 
    colGroup = [this.colYs[ col ]]; // HACK : return only the column we want 
    // get the minimum Y value from the columns 
    var minimumY = Math.min.apply(Math, colGroup); 
    var shortColIndex = col; // HACK 

    // position the brick 
    var position = { 
     x: this.columnWidth * shortColIndex, 
     y: minimumY 
    }; 

    // apply setHeight to necessary columns 
    var setHeight = minimumY + item.size.outerHeight; 
    this.colYs[ shortColIndex ] = setHeight; // HACK : set height only on the column we used 

    return position; 
}; 

Nadzieja to pomaga komuś

3

zainspirowany odpowiedzi Billy'ego (i przez nich odpowiedzi skobaljic za :)) Ja po prostu zmienił inicjalizacji shortColIndex i minimumY osiągnąć to zachowanie. Może być trochę łatwiej plus - przy użyciu rozmiaru colGroup - nadal działają responsywne układy z różnymi kolumnami.

Oto pełna kod v3.3.2:

Masonry.prototype._getItemLayoutPosition = function(item) { 
    item.getSize(); 
    // how many columns does this brick span 
    var remainder = item.size.outerWidth % this.columnWidth; 
    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 
    // round if off by 1 pixel, otherwise use ceil 
    var colSpan = Math[ mathMethod ](item.size.outerWidth/this.columnWidth); 
    colSpan = Math.min(colSpan, this.cols); 

    var colGroup = this._getColGroup(colSpan); 
    // ### HACK: sort by natural order, not by min col height 
    // get the minimum Y value from the columns 
    // var minimumY = Math.min.apply(Math, colGroup); 
    // var shortColIndex = utils.indexOf(colGroup, minimumY); 
    var shortColIndex = jQuery(item.element).index() % colGroup.length; 
    var minimumY = colGroup[shortColIndex]; 

    // position the brick 
    var position = { 
    x: this.columnWidth * shortColIndex, 
    y: minimumY 
    }; 

    // apply setHeight to necessary columns 
    var setHeight = minimumY + item.size.outerHeight; 
    var setSpan = this.cols + 1 - colGroup.length; 
    for (var i = 0; i < setSpan; i++) { 
    this.colYs[ shortColIndex + i ] = setHeight; 
    } 

    return position; 
}; 
+0

Bardzo ci to pomogło! – elju

+0

Świetna odpowiedź i jedyne rozwiązanie, które wydaje się działać – Tom

Powiązane problemy