Ryan Saxe
Ryan Saxe

Reputation: 17869

Call jQuery when something happens

So I am using jQuery Masonry and I want to call some jQuery every time it loads posts:

function manipulate(id) {
    $(id).each(function(){
    if($(this).height()>200){
        $('#container2').append(this);
    } else{
        $('#container').append(this);
    };
  });
};

So I want to call this function every single time that the next item in the Masonry container loads. This way it manipulates the item in the correct manner. How do I do that?

Update: description of Masonry

Masonry is a Javascript plug in that is like CSS floats forced to fit perfectly + infinite scrolling. It completely hides everything that would not be on page 1 if there was no infinite scroll, and then loads them when necessary. This means that my function will not affect any of the hidden items and needs to be recalled whenever Masonry loads the next set of items so that they appear in the right places. This could mean that without knowing Masonry, it is not necessarily possible for you to solve my problem, but you still can. A the end, Masonry "appends" the items to the Masonry container, and then "shows" them. So I guess what I need to do is append them to the correct containers after they have been appended to the Masonry container, but before it gets shown.

Masonry code:

$(window).load(function(){
  var $wall = $('#container');
  $wall.imagesLoaded(function(){
    $wall.masonry({
      itemSelector: '#entry, #entry_photo',
      isAnimated : false
    });
  });

  $wall.infinitescroll({
    navSelector    : '#page-nav',  
    nextSelector   : '#page-nav a',
    itemSelector   : '.entry, .entry_photo',
    bufferPx       : 2000,
    debug          : false,
    errorCallback: function() {
      $('#infscr-loading').fadeOut('normal');  
    }},
    function(newElements) {
      var $newElems = $(newElements);
      $newElems.hide();
      $newElems.imagesLoaded(function(){
        $wall.masonry( 'appended', $newElems,{isAnimated: false}, function(){$newElems.fadeIn('slow');} );
      });
    }); $('.entry').show(500);
  });

I have tried putting the function in the Masonry blocks and even as the $newElems function to see if it will work when more images load, but it does not, and in fact somewhat breaks it.

How can I get it to run all the new elements loaded by Masonry through my jQuery so that they get appended to the right container?

Upvotes: 6

Views: 1321

Answers (3)

Ryan Saxe
Ryan Saxe

Reputation: 17869

So using things said on the answers provided, I messed around and discovered how it was done...so the 'appended' part in imagesLoaded just needed to be replaced with the function! It was really a simple answer...I just had to replace this:

$wall.masonry( 'appended', $newElems,{isAnimated: false},
function(){$newElems.fadeIn('slow');} );

with this:

$wall.masonry(manipulate($newElems) ,{isAnimated: false},
function(){$newElems.fadeIn('slow');} );

Problem solved!

Upvotes: 0

Ford
Ford

Reputation: 2597

You only declared one Masonry instance for container, container2 has no Masonry instance, so it can't infinitely scroll anything. Also, ($(this).height()>200) will always be false if the image has not loaded yet, it'll default to undefined -> 0 > 200, which is always false. Either you need to wait for the image to load before placing it, or somehow get the dimensions of the image when the content is being loaded. You could hide it by default and place it in container, then on imagesloaded, check the height, and move it to the appropriate container and show it.

Upvotes: 1

alianos-
alianos-

Reputation: 916

Another idea is to bind an action to jQuery's .on() ( http://api.jquery.com/on/ ). on() binds on future elements as well, assuming they are properly attached to the DOM (for example through .append() ). So for example you can bind .click() events, on elements that have not been created yet.

Finally you can do a neat trick and make .append() trigger an event. Then attach a handler for that event to the big container where things are appended, so a function is automatically called. Here is a good example of that on append() do something, and a jsfiddle http://jsfiddle.net/rzRVu/

PS. on a sidenote, I see you function takes as input an ID, but then you call .each(). Id's in html code should be unique.

Update. I missed that you tried to do it properly through masonry, what breaks exactly? I see you are calling .imagesLoaded() on a jQuery variable, is that a plugin?

Upvotes: 0

Related Questions