0

On my set I use jquery to fadeout an image, change its source to something else, then fade back in. However, sometimes on slow connections, the image will fade back in before the source completely changes, so the old image will still appear for a brief second before the new one comes in.

Is there a way to have a callback on attr so fading back in is only called when the attr change is reflected?

$(".img").fadeTo("fast",0,function(){
    $(".img").attr({
        //some other stuff
        'src':url
    });
    $(".img").fadeTo("fast",1);
    //other stuff
});

I use fadeTo not fadeIn() so the image size is retained.

Razor Storm
  • 12,167
  • 20
  • 88
  • 148

3 Answers3

2

Bind an event handler to the load event on the image, and fade it out in the handler.

Jimmy
  • 35,686
  • 13
  • 80
  • 98
0

You are wanting to check when the image is loaded? .load() works.

Note: I've never seen it, but I've read that it can be triggered prematurely. So you may want to check the height of the image.

$(".img").fadeTo("fast",0,function(){
  $(this).attr({'src':url});
  $(this).load(function(){ 
    $(this).fadeTo("fast",1);
    $(this).unbind("load");
   });
});
Jason
  • 3,357
  • 1
  • 22
  • 29
  • Wouldn't this do a binding of 'load' onto .img, adding more and more bindings with each time this code is run? Might be safer to add the binding in a global scope. – Razor Storm Oct 28 '10 at 07:46
  • Yes it would. Good catch. I couldn't remember if `.load()` would re trigger if it has already been re-triggered. @Squeegy has a solution below if it does, this one is a solution if it doesn't. I remember something fishy happening when I used to use `.load()`. – Jason Oct 28 '10 at 07:49
  • I added an unbind. Try comparing our code and see if @squeegy is correct. – Jason Oct 28 '10 at 07:51
  • 1
    Chain your jQuery functions, cache them, so that instead of calling `$()` four times, you should only be calling it once – Yi Jiang Oct 28 '10 at 07:58
  • @yi, does chaining guarantee completion of one function before the next runs? I remember doing $("something").fadeOut().fadeIn() a while ago, but it didnt work very well. – Razor Storm Oct 28 '10 at 08:45
0

You need to preload the image, and handle the load event when your image is loaded.

var img = new Image();
$(img).load(function() {
  // Do fading and attr swapping stuff here
  // The new image is already loaded at this point
});

img.src = myImgUrl;

When the img is loaded your function will be called and your fade will happen. The image is now cached and ready to use and will show instantly.

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
  • does a `.load()` on the same element get re-triggered if it has already been triggered once? – Jason Oct 28 '10 at 07:44
  • This example creates a new object for every image that you load, and binds the `load` event exactly once to that object. And even if the image is already loaded, the `load` is event is still triggered and handled. So there is no "same element" here at all since its a new object each time. – Alex Wayne Oct 28 '10 at 16:08