views:

289

answers:

3

I'm trying to create a simple portfolio page. I have a list of thumbs and an image. When you click on a thumb, the image will change.

When a thumbnail is clicked, I'd like to have the image fade out, wait until the image is loaded, then fade back in. The problem I have right now is that some of the images are pretty big, so it fades out, then fades back in immediately, sometimes while the image is still loading.

I'd like to avoid using setTimeout, since sometimes an image will load faster or slower than the time I set.

Here's my code:

 $(function() {
     $('img#image').attr("src", $('ul#thumbs li:first img').attr("src"));

     $('ul#thumbs li img').click(function() {
         $('img#image').fadeOut(700);

         var src = $(this).attr("src");
         $('img#image').attr("src", src);

         $('img#image').fadeIn(700);
     });
 });

<img id="image" src="" alt="" />
<ul id="thumbs">
    <li><img src="/images/thumb1.png" /></li>
    <li><img src="/images/thumb2.png" /></li>
    <li><img src="/images/thumb3.png" /></li>
</ul>
+1  A: 
 $(function() {
     $('img#image').attr("src", $('ul#thumbs li:first img').attr("src"));

     $('ul#thumbs li img').click(function() {
         $('img#image').fadeOut(700);

         var src = $(this).attr("src");
         $('img#image')
             .attr("src", src)
             .load(function() {
                 $(this).fadeIn(700);
             });


     });
 });

<img id="image" src="" alt="" />
<ul id="thumbs">
    <li><img src="/images/thumb1.png" /></li>
    <li><img src="/images/thumb2.png" /></li>
    <li><img src="/images/thumb3.png" /></li>
</ul>
jessegavin
+2  A: 

You can do it like this:

$('img#image').attr("src", src).one('load',function() {
  $(this).fadeIn(700);
}).each(function() {
  if (this.complete) $(this).trigger('load');
});

If an image is cached, in some browsers .load() won't fire, so we need to check for and handle this case by checking .complete and firing load manually. .one() ensures whether it's cached or loaded at that time, that the load handler only fires once.

Nick Craver
Wow. That is nice.
jessegavin
This works the first time I click on a thumbnail. It will wait for the image to load, then fade back in.But if I click on another thumbnail, it will fade back in immediately while the image is still loading.
Steven
@Steven - Which browser you seeing this in?
Nick Craver
@Nick - Firefox 3.6
Steven
@Steven - I may be misunderstanding you, but if it's happening because you click a thumbnail while *another* is still loading and you get this, try `$('img#image').unbind('load')` instead of just `$('img#image')` at the beginning of my answer.
Nick Craver
I couldn't get this solution to work, so I'm just using the normal .load() function.
Steven
@Steven - Be sure to test in all browsers, `.load()` won't fire when the image is cached depending on the browser.
Nick Craver
Thanks, I'll check it out. Do you happen to know which browsers have issues?
Steven
FYI, I got this to work. I finished coding the portfolio, and during testing I noticed that the .load() function wasn't firing in Opera. I remembered this strategy, so I tried it out again, and it's working great. I'm not sure what the problem was the first time. Remarking this response as the answer.
Steven
A: 

You need to queue the animations.

See this page for more info + possible solutions

easement