Hide image until fully loaded

Hi there,

I am loading some content dynamically using the .load() function in jQuery;

The script works like this:


$(document).ready(function(){
  $('.load-button').click(function(){
    $('#target').load('remotepage.html div#object', function(){
      $('#slider').animate({top: -100px});
    });
  });
});

So once the content is loaded, div#slider moves to reveal the new content. The div will move once all the text is loaded but not the images, which is fine. The images will be loading when the viewer first clicks on a.load-button.

What I’d like to do is to hide the image until it is fully loaded into the cache, have an animated ‘loading’ gif as a background image, then BOOM, the image appears in one go with .show();

I’m a little unsure how to approach this, since I’m already using the .load() callback function. I’ve tried using $(window).load(function(show image)), but jQuery dosen’t like that.

Many thanks in advance,
Mike

Have a look at the following post as what you want is called a lazy loader which essentially waits until your cursor or scroll position hits a point in the page in which the image sits.

http://deanhume.com/Home/BlogPost/lazy-loading-images-with-jquery/22

Hi SgtLegend, thanks for your reply.

It certainly looks like a useful plugin, but not quite what I’m after. I basically just want to hide an image until it’s fully loaded. if its not loaded when it comes into view, I just want to have a loading spinner.

Something like:


$('#target').load('somepage.html #object', function){
  if(imageNotYetLoaded){
    $('img').hide();
  }
  imageFullyLoaded{
    $('img').show();
  }
  $('#slider').animate({top:-100px});

#target would have an animated ‘loading’ gif as a background image.

The basic idea is just to change the appearance of the loading of the image from the standard ‘drip-down’ effect to a ‘wait-for-it… BOOM!’ affect.

I’m not 100% sure if images would even load when they’re hidden like that.

After reading this thread I quickly knocked up something that might sort of do what you’re after. (But may mean you need to do some rethinking on how your app currently works…)

  • Will create & inject images using JS
  • Will hide the images until they are loaded
  • Fades them in when loaded
  • Requires a wrapper around the images if you want a loading image to display.

Take a look at http://afterlight.com.au/lab/image-loader/
[I](makes use of console.log, make sure that you have firebug/dev tools open)

[/I]


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Image with Loader</title>
    <style type="text/css">
        .image { background:url(loader.gif) center center no-repeat transparent; float:left; width:500px; margin:5px; }
        .image img { width:100%; }
    </style>
    
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <script type="text/javascript">
        /*     borrowed some code from
            http://letmehaveblog.blogspot.com/2006/08/simple-jquery-plugin-to-load-images.html
            adapted to work a with a more specific purpose
        */
        $.fn.addImage = function(src, fnBefore, fnAfter){ 
           return this.each(function(){
                var i = new Image();
                i.src = src;
                /*    if you want to make sure the loader displays correctly ,
                    you could set CSS width/height here OR you could set a style
                    as I have done.
                */
                //$(this).css({"width":i.width, "height":i.height});
                $(i).fadeTo(0,0);
                fnBefore(i)
                $(i).bind("load", i, fnAfter); 
                this.appendChild(i);
           }); 
        }     


        function beforeLoad(el) {
            console.log("Before image load")
            $(el).fadeOut();
        }


        function afterLoad(e) {
            console.log("After image load")
            $(e.target).fadeTo(500,1)
                //.parent().removeAttr("style");//can remove parent css here if you like
        }
        
        $(document).ready(function(){
            
            $("#image1").addImage(
                "http://placekitten.com/900/900", 
                beforeLoad,
                afterLoad
            );


            $("#image2").addImage(    
                "http://placekitten.com/800/800", 
                beforeLoad,
                afterLoad
            );


        });
    </script>


</head>
<body>
    <div id="content">
        <div id="image1" class="image"></div>
        <div id="image2" class="image" ></div>
    </div>
</body>
</html>



Might not necessarily solve your problem exactly, but should get you on the way :slight_smile:

Wow, yeah, that’s exactly what I want.

Perfect, thanks!

:smiley:

Note that by doing this, people on slow connections will need to wait longer to see the image at all, rather than seeing it progressively as it loads. If it’s a large image, and it’s not what they wanted/expected, they won’t be able to know that until after it’s fully downloaded.

Yep, good point mmj… Something to consider.