jQuery Masonry and Ajax Append Items?

2019-01-17 03:02发布

I am trying to use some ajax and the jQuery Masonry plugin to add some items - but for some reason the new items aren't getting the masonry applied ?

I'm using

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

However the items that are appended subsequently don't have the class="masonry-brick" applied which means that they stuff up completely the positioning ?

13条回答
仙女界的扛把子
2楼-- · 2019-01-17 03:39
var mediaItemContainer = $( '#container' );
mediaItemContainer.masonry( {
    columnWidth:  '210px',
    itemSelector: '.item'
} );
$( mediaItemContainer ).prepend( '<div class="item">foo</div>' );
$( mediaItemContainer ).masonry( 'reloadItems' );
$( mediaItemContainer ).masonry( 'layout' );

Solution

查看更多
Ridiculous、
3楼-- · 2019-01-17 03:39

I found a solution that works fine for me. it reloads every half second the layout of an instance of masonry.

//initialization of a masonry object:

var msnry = new Masonry("#container",{
itemSelector: '#post',
gutter: 15
}); 

//thread that makes the magic happens:

setInterval(function(){
msnry.reloadItems();
msnry.layout();
},500);

this way, you can append things using ajax, and voilá, there is the masonry layout.

查看更多
相关推荐>>
4楼-- · 2019-01-17 03:47

I had the same problem with my ajax listing, i could solve it by calling reloadItems & layouts functions after ajax respond :

var mediaItemContainer = $( '#container' );
mediaItemContainer.masonry( {
    columnWidth:  '210px',
    itemSelector: '.item'
} );
$( mediaItemContainer ).prepend( '<div class="item">foo</div>' );
$( mediaItemContainer ).masonry( 'reloadItems' );
$( mediaItemContainer ).masonry( 'layout' );
查看更多
Juvenile、少年°
5楼-- · 2019-01-17 03:51

You are missing Masonry layout call. According to the docs you need to refresh the layout, executing .masonry() after every change (for instance .masonry('appended')):

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

(source: http://masonry.desandro.com/methods.html)

查看更多
▲ chillily
6楼-- · 2019-01-17 03:52

it is clearly explained here https://masonry.desandro.com/methods.html#prepended

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

in your success function, you need your response "html" to be wrapped in a jquery object and then append using html() or append().

var $content = $( html );
jQuery("#content").append($content).masonry( 'appended', $content );

the final code should be

jQuery.ajax({
    type: "POST",
    url: ajax_url,
    data: ajax_data,
    cache: false,
    success: function (html) {
        if (html.length > 0) {
            var $content = $( html );
            jQuery("#content").append($content).masonry( 'appended', $content );
        }
    });
});
查看更多
爱情/是我丢掉的垃圾
7楼-- · 2019-01-17 03:53

For Masonry v3.2.2 (latest at the time of this post), this is what works:

Assuming newHtml is a string like this:

<li>item 1</li><!--split-->
<li>item 2</li><!--split-->
<li>item 3</li>

You process it like this:

$.get(apiUrl, function(newHtml) {
    var textArr = newHtml.split("<!--split-->");
    var elArr = [];
    $.each(textArr, function(i,v) {
        if (v) {
            elArr.push($(v)[0]);
        }
    });
    $(this).append(elArr);
    $container.waitForImages( function() {
        $container.masonry('appended', elArr);
    });
}

Took me 2 hours to find out this!

查看更多
登录 后发表回答