1

I have the following to lazy-load images:

$(document).ready(function() {
    // lazy load images
    var win = $(window);
    win.on('load resize scroll', function() {
        var viewport = {
            top: win.scrollTop(),
            left: win.scrollLeft()
        };
        viewport.right = viewport.left + win.width();
        viewport.bottom = viewport.top + win.height();

        // cycle through all images (within visible content) and update src attributes
        $('img[data-src]').each(function() {
            var bounds = $(this).offset();
            bounds.right = bounds.left + $(this).outerWidth();
            bounds.bottom = bounds.top + $(this).outerHeight();

            // if image is within viewable area, display it
            if (!(viewport.right < bounds.left || viewport.left > bounds.right ||
                  viewport.bottom < bounds.top || viewport.top > bounds.bottom)) {
                var img = $(this).attr('data-src');
                if (img) {
                    $(this).attr('src', img);
                    $(this).removeAttr('data-src');
                }
            }
        });
    });
});

What I've noticed (at least in Chrome), however, is that sometimes the images won't initially load, but show up as soon as I start scrolling. Any idea why or what is wrong?

EDIT: here is a JSFiddle although reproducing the problem seems to be completely sporadic, I don't know what exactly causes it... Hence why I'm here.

10
  • When asking a question about a problem caused by your code, you will get much better answers if you provide code people can use to reproduce the problem. See: How to create a Minimal, Complete, and Verifiable example Commented Jun 2, 2017 at 17:06
  • added a jsfiddle, not sure what more I can give you. Commented Jun 2, 2017 at 17:10
  • it is the condition, where you compare viewport and bounds - output them to console.log and you will see that only images within the viewport are loaded on load event. Remember that, without src set and the actual picture loaded, the bounded rectangle for img tag is small, browser-specific size. Commented Jun 2, 2017 at 17:19
  • Could it be that before any images load, all images are collapsed to 0px height, thus triggering the load for all images immediately? Commented Jun 2, 2017 at 17:19
  • See this demo: jsfiddle.net/rj64bevj Commented Jun 2, 2017 at 17:26

1 Answer 1

1

You are calling $(window).on('load', fn) inside the $(document).ready callback. To quote the jQuery doc:

Note that although the DOM always becomes ready before the page is fully loaded, it is usually not safe to attach a load event listener in code executed during a .ready() handler.

Better execute the loader function once unconditionally:

$(document).ready(function() {
    var win = $(window);
    function lazyload () {
        //...
    }
    win.on('resize scroll', lazyload);
    lazyload();
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this appears to be the issue! Although sometimes all images are loaded (not lazy-loaded).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.