5

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>
pjmorse
  • 9,204
  • 9
  • 54
  • 124
Steven
  • 18,761
  • 70
  • 194
  • 296

3 Answers3

8

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
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 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 Mar 17 '10 at 21:15
  • @Steven - Which browser you seeing this in? – Nick Craver Mar 17 '10 at 21:43
  • @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 Mar 17 '10 at 21:49
  • I couldn't get this solution to work, so I'm just using the normal .load() function. – Steven Mar 18 '10 at 00:01
  • @Steven - Be sure to test in all browsers, `.load()` won't fire when the image is cached depending on the browser. – Nick Craver Mar 18 '10 at 00:10
  • Thanks, I'll check it out. Do you happen to know which browsers have issues? – Steven Mar 18 '10 at 00:20
  • 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 Mar 22 '10 at 21:57
1
 $(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
  • 74,067
  • 28
  • 136
  • 164
0

You need to queue the animations.

See this page for more info + possible solutions

easement
  • 6,119
  • 3
  • 29
  • 36