2013-07-08 80 views
10

在目录网站上使用砌体。默认情况下,显示的项目按日期排序,然后按部件号排序。我的图像高度不一。问题在于,如果我错了,请纠正我的错误,砌体将第2行第1项放在第1行中最短项目下方,而不是页面左侧。换句话说,当我的数据库返回某个订单时,砌体将这些物品从上到下排列(当高度变化时),而不是从左到右。jQuery砌体排序顺序从左到右而不是从上到下?

我没有找到任何文件来控制这一点。有没有办法迫使砌体保持从左到右的项目顺序,只是基于高度垂直浮动?

我试图张贴一个插图,但显然我没有资格这样做。下面是图中的一个链接:

enter image description here

+0

你就会有问题是1个大的电池可为2个较小的细胞(或更多)一样高。在这种情况下,一个单元格将跨越2行或更多行,我可能会非常困惑。例如,如果你拿第二张插图并将其减少到3列,那么你将堆放高度为3,6和9的盒子。如果你有更多的盒子,你最终会在6点之前拿到盒子7,并且你会继续移动。除非你改变垂直边界来重新对齐盒子,否则我不会看到它是如何完成的。 – Tchoupi

回答

0

简单的答案是“不”

砌体几乎可以肯定重新安排事物,以适应和承担的顺序并不重要。我说“差不多”,因为我认为你说得对,这不是在文档中的任何地方拼写出来 - 但这就是它的工作原理。

3

砌体中没有选项来对项目进行排序,因为它是一个简单的插件,可以逐个放置砖块。选择新的砖块位置很简单:尽可能将砖块放置得更高。

但是在这种情况下可以做的是通过添加两行定义排序来改变脚本,假设所有砖的宽度相同(例如,总是5行)。

为了演示这个,我使用了jQuery Masonry(被压缩),你可以在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

skobaljic's answer启发(这是唯一砌体V2兼容),我已经破解V3做同样的事情。那就是:

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; 
}; 

希望这可以帮助别人

3

比利的回答启发(并为此通过skobaljic的答案:))我只是改变shortColIndex和minimumY的初始化实现这一行为。使用colGroup的大小可能会稍微简单一些,而且具有不同列数的响应式布局仍然有效。

这里是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

非常感谢您的帮助! – elju

+0

伟大的答案和似乎工作的唯一解决方案 – Tom

相关问题