Jonathan Ong
Jonathan Ong

Reputation: 20325

Issue with appending items in jQuery Masonry

I'm trying to do a masonry layout with a bunch of tiles with some containing images. Here's roughly my code:

var $mainContent = $('#main-content');

$mainContent.imagesLoaded(function() {
  $mainContent.masonry()
});

loadMore = function() {
  $.ajax({
    url: '/things',
    success: function (data) {
      var $data = $(data);
      $data.imagesLoaded(function() {
        $mainContent.append($data).masonry('appended', $data, true)
      })
    }
  })
}

$('#load-more').on('click', loadMore)

However, when I run this, I get the following error in Chrome's console:

Uncaught TypeError: Cannot read property 'width' of undefined

Trace:

bB jquery.min.js:2
f.each.f.cssHooks.(anonymous function).get jquery.min.js:4
f.extend.css jquery.min.js:4
f.each.f.fn.(anonymous function) jquery.min.js:4
e.extend.access jquery.min.js:2
f.each.f.fn.(anonymous function) jquery.min.js:4
f.each.f.fn.(anonymous function) jquery.min.js:4
$.Mason._placeBrick jquery.masonry.js:246
$.Mason.layout jquery.masonry.js:172
$.Mason._appended jquery.masonry.js:352
$.Mason.appended jquery.masonry.js:341

I'm using Masonry v.2.1.05 and jQuery v1.7.2

However, when I instead do reload instead of appended, it works like it does in the demos, but I want the posts to be populated from the bottom, and I don't want all the posts to be recalculated.

Do you know what's going on?

I also put this issue on github but I haven't gotten a response yet.

Upvotes: 1

Views: 9903

Answers (3)

Gaurav Kakkar
Gaurav Kakkar

Reputation: 358

Try this solution... this will surely work.

//Initiate your maosnry
$container = $('#container');
$container.imagesLoaded(function(){ 
    $container.masonry({
        itemSelector: '.item'
    }); 
});

//and on ajax call use this to append or prepend
$container.append($data).imagesLoaded(function(){
    $container.masonry( 'appended', $data, true );
}); 

Upvotes: 1

user1854591
user1854591

Reputation: 71

This was exactly what I need to have the animation and have various sized images render correctly:

var el = jQuery(html);
el.imagesLoaded(function() {
    $('#container').append(el).masonry( 'appended', el );
});

Upvotes: 7

Beetroot-Beetroot
Beetroot-Beetroot

Reputation: 18078

I'm not sure this is an answer to the problem but ... bear with me I'm thinking out loud here ...

Given that .append($data) appears inside the $data.imagesLoaded handler, it's not clear how that event would ever fire. I say that based on my understanding that the browser will not attempt to load images until the fragment based on data (presumably an HTML string) has been loaded into the DOM (with .append()).

The following would make more sense:

loadMore = function() {
    $.ajax({
        url: '/things',
        success: function (data) {
            var $data = $(data);
            $data.imagesLoaded(function() {
                $mainContent.masonry('appended', $data, true);
            }).appendTo($mainContent);
        }
    });
};

That said, in your code the imagesLoaded event must fire otherwise why would you get the error? Maybe images do load into an unappended fragment!

Anyway, try my version. I guess it will either work or give the same error as before.

Upvotes: 1

Related Questions