[RESOLVED] How can I slow down JavaScript so it doesn't outrace itself?
I've got an alert written into one of my scripts if an image doesn't load properly.
Image failed to load (Image source: [Image File Name Here]). Click OK to try again
The alert is found in this section of coding:
PHP Code:
if($orig_el_name.toLowerCase() == 'img'){
var $tries = 0;
var $size = new Object();
do{
var $orig_img = new Image();
$orig_img.src = $elem.getAttribute('src');
var $w = $orig_img.width;
$tries++;
if($w === 0){alert('Image failed to load (Image source: ' + $elem.getAttribute('src') + '). Click OK to try again');}
}while($w === 0 && $tries < 10);
if($w === 0 && $tries == 10){
alert('Image Went Bork\r\nImage Source:' + $orig_img.src);
}
var $h = $orig_img.height;
var $or = Number(($elem.width/$w).toFixed(2));
var $r = Number(($elem.width/$w).toFixed(2));
$size.w = $w ;
$size.h = $h ;
$size.or = $or;
$size.r = $r ;
$retrn.size = $size;
}
The variable $w is only 0 if the image for $orig_img fails to load up fast enough--and it happens EVERY TIME the page is loaded. By the time you click on the alert box, the image has loaded, and the script goes along its merry way. But how can I slow down this script WITHOUT an alert box? I do NOT want to annoy my readers, and this script is part of a larger one that lets the readers resize the image for printing.
I'm obviously late to this thread, but I think both loops and timeouts are the wrong approach. You should use events so that the image object notifies *you* when something noteworthy happens.
Code:
// Has it already finished trying to load?
if (someImage.complete) {
// Did it load successfully?
if (someImage.naturalWidth) {
// Success!
} else {
// Fail
}
} else {
// Listen for success or error events
someImage.onload = function () {
// Success!
};
someImage.onerror = function () {
// Fail
};
}
It seems like your script relies on the image. If that's right, then yeah, it should wait until the image is loaded. Just like you need to wait for the DOM ready event before you can safely use the DOM, you also need to wait for the image load event before you can safely use the image.
The timeout will work, but less effectively. If you use a long timeout, such as 2 to 5 seconds, then your script may be waiting longer than it needs to. And if you use a short timeout, such as 50ms, then it'll poll many times before finally triggering the event you were waiting for.
On the other hand, if you have the image notify you when it's ready, then there's no extra waiting and no unnecessary polling.
There's a book sample on my webpage at http://www.mrinitialman.com/BookDemo/ . The pages there (in particular, Introducing (X)HTML and Dynamic Behavior and Scripting) use the script that needs the image sizes. How would you alter the script?
Whether you use timeouts or events, the crucial factor is that the GetSelector function becomes potentially asynchronous. That means GetSelector will need a callback argument to execute when all the data is ready. You'll need to do this even if you stick with the timeout approach. When your code hits the setTimeout statement, your script doesn't pause. It'll queue the function to run again later, but in the mean time, the current invocation will continue to the return statement without the image data.
From what I can tell, you need to 1) accept a callback argument, and 2) execute the callback once the image is verified loaded.
Bookmarks