1

I'm trying to lazy-load images using the following script (lazy-load.js):

function lazyLoadImage(imgContainers) {
    var img = $('<img src="">');
    imgContainers.each(function (i, elm) {
        img.attr('src', $(elm).data("large"));
        img.on('load', function () {
            $(this).addClass('loaded');
        });
        img.addClass('picture');
        $(elm).append(img.clone(true));
    });
}

$(window).on('load',function () {
    var imgContainers = $(document).find(".img-container:not(:has(.loaded))"); // images not loaded yet
    lazyLoadImage(imgContainers);
});

The problem is, everything goes well if I load the script using <script></script> tag but when the script is loaded dynamically using jquery $.getscript() the script is not working consistently (i.e. sometimes the onload event is not triggering). Loading script dynamically:

$.getScript( "path/to/lazy-load.js" )
  .done(function( script, textStatus ) {
    console.log( "script loaded' );
  })
  .fail(function( jqxhr, settings, exception ) {
    console.log( "script not loaded' );
});

So, why the script is not working consistently??

Bipul Roy
  • 506
  • 2
  • 7
  • 18
  • First: Why don't you use the `lazy` attribute to lazyload? Second: If you load the script dynamically then there is no onload function because it already fired. Onload doesn't mean "execute it automatically" it means "execute it once the dom is laoded" And this happens exactly once for every page. – cloned Aug 20 '20 at 09:28
  • @cloned thanks for the hints. Can you explain how can i make it work? – Bipul Roy Aug 20 '20 at 09:33
  • You just have to write: `` and the browser will automatically lazyload images for you! Then you can remove the lazy-load script and save a bunch of unnecessary JS. – cloned Aug 20 '20 at 09:40
  • That would be the easiest solution but I have some animations and effects(blur) are applied and manipulated by the script @cloned – Bipul Roy Aug 20 '20 at 09:55

1 Answers1

1

window.load fires when the window finished loading. It doesn't fire a second time when you load more content via ajax because there is no way to tell for the browser when you will be finished loading additional content. So for all stuff you do via ajax you have to execute all functionality again.

In your case I guess you want these things to happen:

   var imgContainers = $(document).find(".img-container:not(:has(.loaded))"); // images not loaded yet
    lazyLoadImage(imgContainers);

So I would say put this in a function and just call it when you finish loading the script:


function lazyloadimages() {
    var imgContainers = $(document).find(".img-container:not(:has(.loaded))"); // images not loaded yet
    lazyLoadImage(imgContainers);
}

$(window).on('load',function () {
    lazyloadimages(); // notice this change, put the stuff in an extra function so you can reuse it! 
});


$.getScript( "path/to/lazy-load.js" )
  .done(function( script, textStatus ) {
    console.log( "script loaded' );
    lazyloadimages();
  })
  .fail(function( jqxhr, settings, exception ) {
    console.log( "script not loaded' );
    // oh no something went wrong, no need to lazyload something here! 
});
cloned
  • 6,346
  • 4
  • 26
  • 38