javascriptjquerycssjquery-loadjquery-on

Showing a loading image before an image is loaded with jQuery?


I've followed a few different similar questions here on SO but it's not working for some reason. Can someone help me understand why? I want the loading image to show first, then fade out when the bigger image is loaded. The bigger image should fade in.

Fiddle: http://jsfiddle.net/95rpu029/2/

HTML

<article class="project">
    <img width="375" height="375" src="http://dummyimage.com/375x375/000/fff" class="attachment-home-thumb">
</article>

JS

// Show loading image
$('article').prepend('<span class="loading-icon"><img src="http://i.imgur.com/lJpvTU3.gif" height="32" width="32" alt="Loading..."></span>');

// main image loaded ?
$('article img').on('load', function(){
    // hide/remove the loading image
    $('.loading-icon').fadeOut();
    $('article').show();
});

CSS

article.project {
    display: none;
    float: left;
    margin: 0 1% 2%;
    max-width: 375px;
    overflow: hidden;
    position: relative;
    width: 23%;
}

article.project img {
    display: block;
    margin: 0;
    padding: 0;
    max-width: 100%;
    height: auto;
}

Solution

  • This is happening because your test image is quite small and it is already loaded before your code gets a chance to run. So load is not fired (as image already loaded). I have made small change to your code and updated the fiddle. The changes are as follows:

    1. show loader image at start
    2. create an Image object and wire onload of this object
    3. assign it source (the actual image that you want to load)
    4. when event occurs, assign source to original image

      var im = new Image();
      im.onload = function () {
          $("#img2Replace")[0].src = im.src;
      };
      im.src = "http://dummyimage.com/375x375/000/fff";
      

    Well now we have to do this for each image:

        var imgs = $("article.project img.attachment-home-thumb");
        $.each(imgs, function () {
            var $this = $(this);
            var im = new Image();
            im.onload = function () {
                var theImage = $this;
                $this.hide("slow");
                theImage[0].src = im.src;
                $this.show('fast');
            };
            im.src = $this.data("mainsrc");
        });
    

    Note that to simulate delay in loading actual image, I have used setTimeout in fiddle.