title: Bytes received and bytes total of images via Javascript/jQuery
body: <p>I'm working on a Javascript/jQuery powered image preloader, and have hit a bit of a snag. While as of currently it provides the progress based on <code>loaded_images / total_images</code>, this is not very accurate given a page could have a thousand 1kB images, and a single 1MB image.</p>
  
  <p>I'm looking for a way to incorporate filesize into the progress calculations. Now, I've looked into some (cross browser compatible) tricks at capturing the filesize of a given image, and it seems that Ajax requests for <code>Content-Length</code> were the most reliable (in terms of accuracy) like so:</p>
  
  <pre><code>var imageSizeTotal = 0;
  var ajaxReqest = $.ajax({
      type: 'HEAD',
      url: 'path/to/image',
      success: function(message){
          imageSizeTotal += parseInt(ajaxRequest.getResponseHeader('Content-Length'));
      }
  });
  </code></pre>
  
  <p>Now, I find this method to be quite useful, as I can provide a status message of <em>Initializing</em> while the necessary requests are taking place. However my issue now is two-fold:</p>
  
  <ol>
  <li>Is there any way possible to capture the bytes loaded of a given image object, perhaps using <code>setInterval()</code> to periodically check? Otherwise, I'm sort of back at the issue of the progress indicator hanging on large files.</li>
  <li>How can I force the actual progress calculator, etc., portion of the script to wait until the necessary Ajax requests are completed (displaying <em>Initializing</em> or whatever), so it can go ahead with the loading?</li>
  </ol>
  
  <p>Also, here's the script I currently use, which again, calculates progress based on the number of images, regardless of filesize or bytes received.</p>
  
  <pre><code>var preloaderTotal = 0;
  var preloaderLoaded = 0;
  var preloaderCurrent = null;
  
  $('#preloaderCurtain')
      .bind('preloaderStart', function(){
          $(this)
              .show();
          $('*')
              .filter(function(e){
                  if($(this).css('background-image') != 'none'){
                      preloaderTotal++;
                      return true;
                  }
              })
              .each(function(index){
                  preloaderCurrent = new Image();
                  preloaderCurrent.src = $(this).css('background-image').slice(5, -2);
                  preloaderCurrent.onload = function(e){
                      preloaderLoaded++;
                      if(preloaderLoaded == preloaderTotal - 1){
                          $('#preloaderCurtain')
                              .trigger('preloaderComplete')
                      }
                      $('#preloaderCurtain')
                          .trigger('preloaderProgress')
                  };
              });
      })
      .bind('preloaderComplete', function(){
          $(this)
              .fadeOut(500)
          startAnimation();
      })
      .bind('preloaderProgress', function(e){
          $('#preloaderProgress')
              .css('opacity', 0.25 + (preloaderLoaded / preloaderTotal))
              .text(Math.floor((preloaderLoaded / preloaderTotal) * 100) + '%');
      })
      .trigger('preloaderStart');
  </code></pre>
  
  <p>Hopefully I'll be able to turn this into a plugin, once I work the bugs out of it.</p>