jQuery砌体和Ajax追加项目?

31

我正在尝试使用一些 AJAX 和 jQuery Masonry 插件来添加一些项目 - 但不知何故新项目没有应用 masonry?

我正在使用:

jQuery.ajax({
    type: "POST",
    url: ajax_url,
    data: ajax_data,
    cache: false,
    success: function (html) {
        if (html.length > 0) {
            jQuery("#content").append(html).masonry( 'appended', html, true );
        }
    });
});

然而,随后添加的项目并没有应用 class="masonry-brick",这意味着它们完全破坏了位置的布局?


你能展示一下砌体的定义吗?我的意思是,第一次调用砌体时。 - fuzzyalej
13个回答

43

看起来 masonry 函数期望第二个参数是 jQuery 对象,而不是原始的 HTML 字符串。你可以通过像这样包装成功回调参数来修复它:

jQuery.ajax({
    type: "POST",
    url: ajax_url,
    data: ajax_data,
    cache: false,
    success: function (html) {
        if (html.length > 0) {
            var el = jQuery(html);
            jQuery("#content").append(el).masonry( 'appended', el, true );
        }
    });
});

1
谢谢回复!嗯,我试过了,但它似乎仍然不能正常工作。不确定为什么它不接受原始的HTML字符串? - Andy
我也试过了!真不敢相信这就是问题所在。 - bigtex777
这个方法非常好用。它在文档 http://masonry.desandro.com/methods.html 中没有提到。 - Panama Jack
如果不使用jQuery,您有任何想法如何完成这个任务吗? - deweydb
我也试过了,太神奇了。 - Adil Aijaz
显示剩余2条评论

28
var mediaItemContainer = $( '#container' );
mediaItemContainer.masonry( {
    columnWidth:  '210px',
    itemSelector: '.item'
} );
$( mediaItemContainer ).prepend( '<div class="item">foo</div>' );
$( mediaItemContainer ).masonry( 'reloadItems' );
$( mediaItemContainer ).masonry( 'layout' );

解决方案


瀑布流布局('layout')是关键!谢谢! - X9DESIGN
这个救了我...那个砌体('layout')完成了它 - jsdev

24

我曾遇到类似的问题,不过我使用了以下这行代码(已为您转换成适合您的代码)。很抱歉,我不记得我在哪里找到它了。

在您的代码中将其替换为:

jQuery("#content").append(el).masonry( 'appended', el, true );

使用以下代码:

jQuery("#content").append(el).masonry( 'reload' );

http://masonry.desandro.com/methods.html


2
我也试过了,看起来你不能重新应用砖石布局,而是必须调用reload。我使用了以下代码:if(!$('#results').hasClass('masonry')) { $('#results').masonry({ itemSelector: '.product' }); } else { $('#results').masonry('reload'); } - Kris
14
“reload”砌体并非真正的解决方案,而只是一种权宜之计。这可能会带来巨大的性能开销。想象一下,试图向一个由200多个图片组成的砌体网格中添加一张图片,并重新加载整个网格。 - PUG
“reload”似乎不再是一个有效的方法。我认为你需要使用“reloadItems”代替。 - Mike Garcia
有趣的是,实际上起作用的是他说要替换的那个。那个才是有效的。http://masonry.desandro.com/methods.html - Panama Jack
如果您有超过60个图像项需要加载,就不应该使用“reload”。请改用“appended”,因为它只会为新加载的项计算布局。如果“appended”对您无效,则需要检查您的CSS / JS。 - ksiomelo
控制台错误信息:“masonry实例没有'reload'方法” - Cichy

5
success: function (response) {
  if(response.length > 0) {
     var el = js(response); 
     setTimeout(function () {
       js("#masonry").append(el).masonry( 'appended', el).masonry('layout');
     }, 500);
  }
}   

对我来说很好用。


4

以下方法适用于我。当我在网页上点击“加载更多”按钮时,我的Ajax会返回一组HTML项(从Ajax返回部分视图)。下面是动态生成的部分视图。

foreach (var item in Model.SocialFeedList)
{
        <div class="grid-item">
            <div class="grid-inner">
                <div class="img-holder" style="background-image:url(imageURLHere)">
                </div>
                <div class="content-area">
                    <h3><a target="_blank" href="SomeLink">TitleOfTheLink</a></h3>
                    <p>SomeDescription</p>
                    <h5 class="date"><span>Published</span>: 2016/07/13</h5>
                </div>
            </div>
        </div>
}

在成功回调ajax方法中,我已经执行了以下操作,其中"response"是我从上面的html中获取的一组html项。其中"divFeedList"是我显示一组html元素的根元素。
请看下面的代码: jQuery("divFeedList").append(response).masonry('reloadItems', response, true).masonry(); 如果答案不清楚,请让我知道。

3

我在append命令后添加了以下代码,一切都很好:

$grid.imagesLoaded().progress( function() {
    $grid.masonry('layout');
});

原因:

未加载的图片可能会破坏Masonry布局并导致元素重叠。imagesLoaded可以解决这个问题。 imagesLoaded是一个单独的脚本,您可以在imagesloaded.desandro.com下载。

源代码


1

你缺少了瀑布流布局的调用。根据文档,你需要在每次更改后刷新布局,执行.masonry()(例如.masonry('appended')):

$grid.masonry()
  .append(elem)
  .masonry('appended', elem)
  // layout
  .masonry();

(来源:http://masonry.desandro.com/methods.html


1

我遇到了与我的Ajax列表相同的问题,通过在Ajax响应后调用reloadItemslayouts函数,我解决了这个问题:

var mediaItemContainer = $( '#container' );
mediaItemContainer.masonry( {
    columnWidth:  '210px',
    itemSelector: '.item'
} );
$( mediaItemContainer ).prepend( '<div class="item">foo</div>' );
$( mediaItemContainer ).masonry( 'reloadItems' );
$( mediaItemContainer ).masonry( 'layout' );

0
仅供未来遇到此问题且上述解决方案无法解决的人参考:我发现我的选择器和我添加的元素大小写不一致,即itemSelector.Card,但我却添加了<div class="card">
希望这可以帮助到你。

0

这个解决方案对我有效:

  jQuery.ajax({
    type: "POST",
    url: ajax_url,
    data: ajax_data,
    dataType: 'json',
    cache: false,
    success: function(response) {
      if (response.length > 0) {
        var $container = $('#container');
        var msnry = $container.data('masonry');
        var elems = [];
        var fragment = document.createDocumentFragment();
        for (var x in response) {
          var elem = $(response[x]).get(0);
          fragment.appendChild(elem);
          elems.push(elem);
        }
        $container.appendChild(fragment);
        msnry.appended(elems);
      }
    }
  });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接