1

I am using .load() in jQuery to load in html content, but in this content there are 3/4 images embedded. The success event only fires on .load() when all the html is loaded in and not actually the images, does anyone know a way of preloading the full content of a page?

$('#ajax_loader').hide().load('page.html',function(){
  $(this).fadeUp(1000);
});

This is my simple code (rest of it is in the full app), loading in the following code (ie. page.html)

<div>
  <div id="slideshow">
    <img src="images/img1.jpg" />
    <img src="images/img2.jpg" />
    <img src="images/img3.jpg" />
  </div>
  <p>This is some sample content</p>
</div>
gblazex
  • 49,155
  • 12
  • 98
  • 91
benpalmer
  • 2,057
  • 3
  • 17
  • 21

3 Answers3

3

I suggest that you don't use a fadeIn animation after the images are loaded because of performance degradation it brings. It is usually a good idea to fadeIn the content then start loading the images to ensure that the animation is smooth for as many users as possible.

Having said that, of course you can accomplish your original goal if you want to stick with it:
Use a 1x1 blank image as the image src attribute and store the real url in the title.

<div>
  <div id="slideshow">
    <img src="blank.gif" title="images/img1.jpg" />
    <img src="blank.gif" title="images/img2.jpg" />
    <img src="blank.gif" title="images/img3.jpg" />
  </div>
  <p>This is some sample content</p>
</div>

And your code becomes:

$('#ajax_loader').hide().load('page.html', function(){
  var c = 0;
  var images = $("#slideshow img");
  images.load(function(){
    if (++c == images.length) {
      $('#ajax_loader').fadeIn(1000);
    }
  });
  images.each(function(){
    this.src = this.title;
  });
});
gblazex
  • 49,155
  • 12
  • 98
  • 91
  • Thanks man, this worked a treat! Almost too good, now we've got a 15 second wait before content (but that's another story). Thanks for your help! – benpalmer Jun 12 '11 at 21:45
2

The images are loaded with separate HTML requests, and obviously the browser can't even start loading them until the HTML in the response has been parsed.

If you know the URLs of the images before you load the content, then you can preload them by creating "Image" elements and waiting for them to load (that is, by handling their "load" events individually).

var imgUrls = [ "images/img1.jpg", "images/img2.jpg", "images/img3.jpg" ];
var c = 0;

for (var i = 0; i < imgUrls.length; ++i) {
  var img = new Image();
  img.onload = function() {
      c += 1;
      if (c == imgUrls.length) {
        // at this point all images are loaded
        // ...
      }
  };
  img.src = imgUrls[i];
}

edit — @galambalazs pointed out that the closure around the handler was (in this case) unnecessary.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • So I could put this script on the page i am loading in and then not fadeIn the content until i fire an event inside where you have the comments? – benpalmer Jun 12 '11 at 16:39
  • Well, using ".load()" to load an *entire page* inside an existing DOM doesn't make a lot of sense - ".load()" is intended to be used to load *fragments* of pages into an existing DOM. My suggestion here is that you'd do this in the page that invokes ".load()" before doing that, as then the browser would have cached the images by the time that operation is finished. – Pointy Jun 12 '11 at 16:46
  • I'm not necessarily loading in a whole page, just images and text with a bit of markup. I don't understand how you would be able to find the URLs of the images without doing a database call with php. – benpalmer Jun 12 '11 at 16:58
  • Well yes I agree. If you're loading a fragment, however, there's not going to be a "load" event other than the success event that's part of the ajax call. The images are all loaded with separate HTTP requests (because that's just how `` tags work). You could use an interval timer or something to check for when the "complete" property on all the images is true, I guess. What's your overall goal here? – Pointy Jun 12 '11 at 17:09
  • 1
    @Pointy - It is unnecessary to wrap event handlers to immediately executing functions, because both `c` and `imgUrls` can be shared between them. For the same reason making individual functions in a loop is a needless overhead here. – gblazex Jun 12 '11 at 17:21
  • @galambalazs - ah yes you're right; I'm just in the habit here because about every 3rd question is about that (potential) error :-) Thanks! – Pointy Jun 12 '11 at 17:35
-1

Check out this similar situation

It seems that the main fix to your problem would be the correct use of the .ready and the .load operator. If used properly, you can wait until all elements and media items are loaded into the browser before a response is passed to its handler. I don't want to plagerize too much :) and its a really great answer.

Community
  • 1
  • 1
Michael Jasper
  • 7,962
  • 4
  • 40
  • 60
  • Thanks for the answer, but this doesn't seem to cover DOM elements loaded in dynamically, only on the main page request. – benpalmer Jun 12 '11 at 16:55