【问题标题】:jQuery Masonry sort order left to right rather than top to bottom?jQuery Masonry 排序顺序从左到右而不是从上到下?
【发布时间】:2013-07-08 20:33:19
【问题描述】:

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

我在文档中找不到任何可以控制这一点的内容。有没有办法强制 Masonry 保持物品从左到右的顺序并根据高度垂直浮动?

我试图发布插图,但显然我没有资格这样做。这是插图的链接:

【问题讨论】:

  • 您将遇到的问题是 1 个大单元格可能与 2 个较小单元格(或更多)一样高。在这种情况下,一个单元格将跨越 2 行或更多行,我可能会很困惑。例如,如果您使用第二个插图并将其减少到 3 列,您将堆叠盒子 3、6 和 9,它们都是高的。你会在第 6 个之前得到第 7 个盒子,如果你有更多的盒子,你会继续移动。除非您改变垂直边距以重新对齐框,否则我看不出它是如何完成的。

标签: jquery jquery-masonry


【解决方案1】:

受比利的回答启发(因此受到 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;
};

【讨论】:

  • 感谢您的帮助!
  • 很好的答案和唯一可行的解​​决方案
【解决方案2】:

Masonry 中没有对物品进行排序的选项,因为它是一个简单的插件,可以一一放置砖块。选择新砖的位置很简单:尽可能把它放在更高的位置。

但是在这种情况下可以做的是通过添加定义排序的两行来更改脚本,假设所有砖块的宽度相同(例如,总是 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;
};

【讨论】:

  • 你必须编辑砌体文件或之后添加它就足够了吗?
  • 该脚本是在 Mason 核心之后添加的。
【解决方案3】:

简单的答案是“不”

砌体几乎按照定义重新排列事物以适应并假设顺序并不重要。我说“几乎”是因为我认为您是对的,文档中的任何地方都没有说明这一点——但这就是它的工作原理。

【讨论】:

    【解决方案4】:

    看看 Masonry Ordered。我没有对此进行测试,但看起来它可能是您正在寻找的解决方案:http://masonry-ordered.tasuki.org/options/

    【讨论】:

      【解决方案5】:

      skobaljic's answer(仅与 Masonry 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;
      };
      

      希望这对某人有所帮助

      【讨论】:

        【解决方案6】:

        我已经解决了这个问题,只需将 masonry.js 替换为 isotope.js。因为它有水平对齐选项。我就是这样做的-

        将类“horizo​​ntal-order-class”添加到具有类行的 div。

        <div class="row horizontal-order-class">
         <div class="col-lg-4 col-md-6 mb-25 ">...</div>
         ---
        </div>
        

        然后在添加isotope.js后,在页脚的脚本标签中添加以下代码。

        $('.horizontal-order-class').isotope({
                    itemSelector: ".col-lg-4, .col-md-6", //the next div or the column elements that need to be arranged
                    masonry: {
                        horizontalOrder: true, //setting horizontal order as true, by default it will  be false.
                    }
                });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-23
          • 2015-06-20
          • 2022-01-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-02
          • 2014-08-16
          相关资源
          最近更新 更多