   [web] pre-loading images
  I have a web page which is part of a web-based game which is used to allow the user to create a character.As part of character creation, they're given the choice of a character portrait.  They can choose one from a large number of portraits used to identify their character and give some identity to them beyond just a name.I display smaller versions the portraits in a table and the user can click on one to choose it.  As they mouse over the smaller portrait images, larger versions of them are shown.Running locally everything works great (of course).  Running from a remote internet client, there can be a good amount of delay and sluggishness waiting for the images to load.So, I'm interested in using &#106avascript to preload the images to the client.  I've seen techniques on how to do this in the page header.  Although this would work, I'm concerned that with a large number of images there would be quite a bit of delay before any sort of visual feedback.Any suggestion on how to do the pre-loading, but display a progress bar or something while the loading runs?I suspect that showing a load page, loading the images, then re-directing to the real page wouldn't work as the re-direct would flush the loaded images, but I'm not entirely sure about that.Any ideas?   
  I'm not sure how to do it outside of the page header, to be honest.As far as displaying a loading image or some other notification, you might be best of using some small Flash apps in your page.   ;  ok, I've got it working.  here's what I've done in case someone else stumbles across this in the future.I have a &#106avascript function which gets called when the page is loaded.  The &#106avascript function loads a single image, then sets a very short timer which will re-call the same function (10ms) unless all the images have been loaded in which case it stops and doesn't get called again.  So it works its way through an array, loading all needed images, but it isn't a tight loop, its based off the timer so hopefully it wont prevent other &#106avascript event handlers, etc. from being called.The PHP script which generates the page also generates the client-side &#106avascript array from which the above loading function works.  The array contains all possible images needed.Each time the &#106avascript function loads a new image, it updates a progress bar on the page.  The progress bar was created using a table with 2 cells, one with a background color, one without inside a parent table which has a border.  Each time the function loads another image, it re-generates this table into a DIV tag on the page.  When done, it clears it out.  The width of the cells are num_loaded for one and (total_needed - num_loaded) for the other, resulting in the progress bar showing how many of the total # images have been loaded.The end result is that when the page loads, you get a progress bar which updates as all the images load and then goes away once loading is finished.  While loading you can continue to interact with the page.  And the progress bar looks as good as something you'd generate using an applet/etc.EDIT: one additional note; I initially tried preloading by just setting the src property of each image and moving on.  I found that setting the src and continuing on doesn't mean the image has actually finished loading.  so now in my image preload function i don't move on to the next image until I've verified the image I asked to load has finished loading (by checking the image.complete property).  with this in place its working like a gem.[Edited by - coder1024 on January 7, 2006 4:27:13 PM];  The problem with your solution, however, is that it's a synchronous solution; it loads everything and then you can interact with the page. It's a good one if you want this to happen, but if you're doing a lot of complex server-side magic, it's going to take a bit of time to load.Setting the src for the images is guarenteed asynchronous, as &#106avascript simply tells the browser to fire the GET request and moves on with execution of the script. In my experiences, it's best to go for the middle ground here; load what you absolutely need (things like any chrome or decorations, stuff like that) using a function called through setInterval, and once these things are done loading, to load the rest in the background. It's how I provide my up-and-coming with seemless tile refreshes (browser-side caching offscreen objects in all four directions).I'm glad you figured it out though!   ;Quote:Original post by ciroknightThe problem with your solution, however, is that it's a synchronous solution; it loads everything and then you can interact with the page.Not necessarily. The way I understood it, he just checks the previous image's complete flag and if it's false just does nothing and checks again the next time round etc. This way it's asynchronous. If the function just waits until image.complete is true, then it might be synchronous, although I'm not entirely sure if it is even then, because I thought browsers execute scripts in separate threads (no?).   ;Quote:The problem with your solution, however, is that it's a synchronous solution; it loads everything and then you can interact with the page.no, the image loading is asynchronous.  you can immediately interact with the page and it'll just keep on loading images in the background.  the &#106avascript function is periodically called using a timer and just checks the completed property and moves on to the next image once the current one has completed.  so its up to the user.  there's nothing about the solution which would force them to wait for anything.  i.e., the function doesn't sit and wait for completion, it just checks for completion and returns after setting a timer to trigger the next call.  if, when checking, the image has completed it then advances to the next image, setting its src property and again immediately returns.  so other processing is free to continue without waiting.Quote:Setting the src for the images is guarenteed asynchronous, as &#106avascript simply tells the browser to fire the GET request and moves on with execution of the script.which is what i want.  this allows me to just set the src property, and move on.  i then periodically check the completed flag and once that image has completed, i  move along and set the src for the next image.Quote:In my experiences, it's best to go for the middle ground here; load what you absolutely need (things like any chrome or decorations, stuff like that) using a function called through setInterval, and once these things are done loading, to load the rest in the background.I currently have it setup to load everything in the background to avoid any waiting.  Although, your approach sounds like a good idea (forcing some things to be synchronously pre-loaded before the user can do anything) for some minimal set of UI imagery needed to present the basic page.Quote:It's how I provide my up-and-coming with seemless tile refreshes (browser-side caching offscreen objects in all four directions).google maps does an excellent job of this.  I'm haven't looked closely enough to see exactly what they're doing though.Quote:Not necessarily. The way I understood it, he just checks the previous image's complete flag and if it's false just does nothing and checks again the next time round etc. This way it's asynchronous. If the function just waits until image.complete is true, then it might be synchronous, although I'm not entirely sure if it is even then, because I thought browsers execute scripts in separate threads (no?).thats correct.  i use the timer and let the function get called separately for each check just to be on the safe side as i dont want to sit in a loop since i have other &#106avascript functions i need to ensure get called while the preloading is happening.  for example, when you click on radio buttons on the page, &#106avascript dynamically updates other parts of the page and i wanted that to be interactive even during the preloading.   ;  You can create an array, and fill it with &#106avascript Image objects. Each of these Image objects, then you can set the src property to the image location you want to preload.If you want, you can hook the "load" event of each image, and have them decrement a counter or something, so you can show the user progress.I'm not entirely sure how reliable this is, perhaps the "load" event won't fire at all if the image is already cached (although of course, it should).The Image objects won't be part of the document and won't therefore display at all. This preloading simply ensures that if and when you do create an image from one of these files, it will already be in the browser's cache, and hence fast.Mark   