Binding image lazy loading to new images inserted after ajax request
Asked Answered
A

2

10

I'm using Mika Tuupola's Lazy Load plugin http://www.appelsiini.net/projects/lazyload to delay loading images as you scroll down a long image gallery. The problem is after 10 images, I use infinite scrolling so I fetch the next 10 images, and append them via ajax. Lazy Loading no longer works on this next batch of appended images.

It's a pretty javascript-heavy image gallery, so for everything else (such as tooltips, modal overlays, etc) I've been using jQuery's delegate() to bind to ajax-inserted elements. The problem with the Lazy Load plugin is that I'm not sure what event to bind to.

So say I want to lazy load images with a class of "lazy". I would write this:

$("img.lazy").lazyload({ 
    effect: "fadeIn" 
});

and it works for the first 10 images, but stops working after inserting more via ajax. The only thing I can think of is to use delegate on a load event, like so:

$(document).delegate("img.lazy", "load", function(event) {  
    $(this).lazyload({ 
         effect: "fadeIn" 
    });     
});

but that breaks everything. Thanks!

EDIT: The jQuery I use to load more records (this is a Rails app):

$(window).scroll(function() {
    var url;
    url = $(".pagination .next_page").attr("href");
    if (url && $(window).scrollTop() > $(document).height() - $(window).height() - 50) {
    $(".pagination").html("<p>loading more images...</p>");
    return $.getScript(url);
    }
});

$(window).scroll();
Afghan answered 5/4, 2012 at 21:4 Comment(3)
@Fresheyeball .on with what event? That's what he's asking.Barfuss
why not try using .on on lazyload? wouldn't that work?Tartlet
@Tartlet Again, with what event? lazyload isn't an event, and .on requires an event to bind to.Barfuss
B
17

I would use the ajaxStop method.

$("img.lazy").lazyload({ 
    effect: "fadeIn" 
}).removeClass("lazy");
$(document).ajaxStop(function(){
    $("img.lazy").lazyload({ 
        effect: "fadeIn" 
    }).removeClass("lazy");
});

removeClass prevents double initialization.

Barfuss answered 5/4, 2012 at 21:16 Comment(3)
Wow, thank you that worked like a charm. Now I just need to understand how exactly ajaxStop() solved the problem (I read this api.jquery.com/ajaxStop but still a bit confused). Is it performance-friendly?Afghan
It is performance friendly, however it would be even better if you instead placed it in the callback of the specific ajax request that is updating the page.Barfuss
@Afghan - extending Kevin B's comment. The deferreds object is your friend in this scenario. See: api.jquery.com/category/deferred-objectFreewheeling
M
0

In addition to Kevin B's answer if you want to avoid ajaxStop jQuery now defines a when() function for that purpose

// the following code will be executed when the ajax request resolve.
// the ajax function must return the value from calling the $.ajax() method.

    $.when(load_new_image(1), load_new_image(2), load_new_image(3)).done(function(i1, i2, i3){

            if($('img.lazy').length){

                 $('img.lazy').lazyload({ 

                          effect:'fadeIn'

                 }).removeClass('lazy').addClass('lazyloaded');

            }

        });

        function load_new_image(image_id) {

            return $.ajax({
                url: "someUrl",
                dataType: "json",
                data:  yourJsonData,            
                ...
            });
        }

from: http://api.jquery.com/jQuery.when/

Moser answered 20/10, 2014 at 20:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.