Loading images as they become available
Currently working on a project that required me to create an image upload and processing factory. Basically, it allows you to upload media (photos and video) and then processes media, encodes video, resize images etc.
The problem: After uploading a batch of images, the user is brought to a page where they may name each photo they just uploaded and add descriptions. However, since we allow them to upload many photos at once, the images are not available right away. So they will see a default placeholder image until the new oneĀ is availble. When the new image is loaded, we use javascript to change the image on the page, without reloading.
The solution: a little javascript, a little jQuery.
Let’s start by creating a simple demo html:
<!doctype html> <html> <head> <script type="text/javascript" src="js/jquery-1.4.1.min.js"></script> <script type="text/javascript"> </script> </head> <body> <h1 id="loader">Loading Images</h1> <p><img src="images/default.gif" border="0" id="1" class="dynImg" /></p> <p><img src="images/default.gif" border="0" id="2" class="dynImg" /></p> <p><img src="images/default.gif" border="0" id="3" class="dynImg" /></p> <p><img src="images/default.gif" border="0" id="4" class="dynImg" /></p> <p><img src="images/default.gif" border="0" id="5" class="dynImg" /></p> </body> </html>
You should notice that there are six images that we will load and they all have unique id’s but the same class name. Our javascript will use the unique id to locate the file names. For the sake of this demo our loaded images will be named according to the id’s so we will be attempting to load 1.gif, 2.gif, 3.gif all the way up to 6.gif
Let’s begin to add our javascript. First let’s create a function to select the image collection and update each image. the function will be named updateDynImg().
<script type="text/javascript"> function updateDynImg() { $('img.dynImg').each(function(){ // Do something. }); } ; </script>
Above shows how we use jQuery to select all class names of “dynImg” that happen to be img tags and loop over each one in the collection using the each function.
Now let’s set a few variables, create an image object, use that to check if the image exists and then create a new function to call when the image loads successfully.
<script type="text/javascript"> function updateDynImg() { $('img.dynImg').each(function(){ var EID = this.id; var URL = "images/"+EID+".gif"; var tester=new Image(); tester.onload=isGood; tester.src=URL; function isGood() { document.getElementById(EID).src = "images/"+EID+".gif"; } }); } ; </script>
This is the meat of our script above. It’s pretty god damn basic. but it works. If you were to load images into your images directory now it will load. Of course after a page refresh since we have not set our interval yet.
There are a couple other things we will need to update as well. First, let’s create a new function to run this function when the page loads and set an interval to run every 5 seconds. We can paste this directly below the first function.
$(document).ready(function(){ // run the kickoff update. updateDynImg(); //set the interval to run update. setInterval("updateDynImg()", 5000) });
Pretty straightforward, not gonna go into detail there. Now, to solve some problems with browser caching when attempting to load these images we will add a random number to each image.
function updateDynImg() { $('img.dynImg').each(function(){ var randomnumber=Math.floor(Math.random()*10001); var EID = this.id; var URL = "images/"+EID+".gif?id="+randomnumber; var tester=new Image(); tester.onload=isGood; tester.src=URL; function isGood() { document.getElementById(EID).src = "images/"+EID+".gif"; } }); } ;
Easy enough. Now I want to make sure I am not running a check if the image is already loaded. So let’s just make sure that the src of the current image is the default.gif (must use absolute paths for this).
function updateDynImg() { $('img.dynImg').each(function(){ var randomnumber=Math.floor(Math.random()*10001); var EID = this.id; var URL = "images/"+EID+".gif?id="+randomnumber; var tester=new Image(); var myRoot = location.href.match(/^.*\//); if (this.src == myRoot+"images/default.gif") { tester.onload=isGood; tester.src=URL; } function isGood() { document.getElementById(EID).src = "images/"+EID+".gif"; } }); } ;
Excellent! Nearly done. Now I just want to update the header to show how many images are loaded and the total number of images. I wont break that down so here is the full javascript block. Go ahead and test it locally, just rename your images or drag them in and out of the directory and watch them update automatically. Fun with Javascript!
<script type="text/javascript"> function updateDynImg() { var numOfLoaded = 0; var totalImages = $('img.dynImg').length; $('img.dynImg').each(function(){ var randomnumber=Math.floor(Math.random()*10001); var EID = this.id; var URL = "images/"+EID+".gif?id="+randomnumber; var tester=new Image(); var myRoot = location.href.match(/^.*\//); if (this.src == myRoot+"images/default.gif") { tester.onload=isGood; tester.src=URL; } else { if (numOfLoaded != totalImages) updateLoader(); } function isGood() { document.getElementById(EID).src = "images/"+EID+".gif?id="+randomnumber; if (numOfLoaded != totalImages) updateLoader(); } // This will update the h1 loader tag. function updateLoader(){ numOfLoaded = numOfLoaded + 1; $("#loader").replaceWith('<h1 id="loader">Loading Images '+numOfLoaded+' of '+totalImages+'</h1>'); } }); } ; $(document).ready(function(){ // Run the kickoff update. updateDynImg(); // Set the interval to run update. setInterval("updateDynImg()", 5000) }); </script>
| Print article | This entry was posted by admin on February 6, 2010 at 3:12 am, and is filed under Uncategorized. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |
