PDA

View Full Version : IE6 & re-get preloaded images



yardbird
06-27-2005, 03:55 AM
Hey all,

Need some help with IE6 and problem with random slide show.

Problem is, every time the image changes, IE goes out to the net to re-get the image, even though all are preloaded. Firefox works fine and seems to use the preloaded images.

I have put the following in my .htaccess and verified that the expiration on the headers for these images is a month out.

BrowserMatch "MSIE" brokenvary=1
BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1
BrowserMatch "Opera" !brokenvary
SetEnvIf brokenvary 1 force-no-vary
ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/gif A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/png A2592000


I have tried all the settings in IE regarding when the reload of the page takes place, though in truth, automatic is the default setting, and what most users will have. None make a bit of difference anyway. IE continues to re-get the image from the network.

So - - - at this point it's either something about my javascript that I don't see or something about IE I don't know.

*******
CODE
*******

dog_array = new Array();

/* 1) preload dog face images, giving them names. Use array for randomizing by index. (if javascript allowed)
Use this method - some free javascript methods download the image file again for each display !
*/

darla = new Image(100,100); darla.src = "images/faces/Darla100.jpg"; dog_array[dog_array.length] = 'darla.src';
beamer = new Image(100,100); beamer.src = "images/faces/Beamer100.jpg"; dog_array[dog_array.length] = 'beamer.src';
ebony = new Image(100,100); ebony.src = "images/faces/Ebony100.jpg"; dog_array[dog_array.length] = 'ebony.src';

{ more dogs - - - yada yada yada }


/* showRandFace function - requires 2 arguments
1) time - number of milliseconds to leave each slide in place
2) numpic - image in array currently showing
*/
function showRandFace(time, numpic) {
face_num=numpic;

// while randomly selected image is same as last image shown, select another
while (numpic==face_num) {
face_num=parseInt(Math.random()*dog_array.length); // select random image
face_num=(isNaN(face_num))?0:face_num; // set to zero if results undefined}
}
if (document.images)
{
document.images['slide'].src = eval(dog_array[face_num]); // replace the image
}
setTimeout("showRandFace("+time+","+face_num+")",time); // recursive call after specified milliseconds
}

dog_num=parseInt(Math.random()*dog_array.length); // select image
dog_num=(isNaN(dog_num))?0:dog_num; // set to zero if results undefined
document.write("<img src='"+dog_array[dog_num]+"' id='faces' name='slide' border='0' hspace='5' vspace='0' align='top'>");
showRandFace(2500,0);

*****

Thanks in advance for reading this and any help you may give.

Twey
06-27-2005, 07:36 AM
dog_array[dog_array.length] = 'beamer.src'
The quotes you put around "beamer.src" mean you're literally assigning dog_array[dog_array.length] "beamer.src" instead of the actual source of the image.
Take 'em out.

mwinter
06-29-2005, 01:08 AM
The quotes you put around "beamer.src" mean you're literally assigning dog_array[dog_array.length] "beamer.src" instead of the actual source of the image.That shouldn't actually matter. The array elements are evaluated using the eval global function, however that's just as bad.



Problem is, every time the image changes, IE goes out to the net to re-get the image, even though all are preloaded.I've encountered preloading weirdness with IE as well, but I'm a little fuzzy on the details at the moment. As I recall, if the preloading process was interrupted, IE would just stop trying, necessitating a network request next time around. I believe Firefox just keeps going. That may have no bearing on the problem at hand, though.

Can you provide a link to a test page so that we can see exactly what's going on?



face_num=parseInt(Math.random()*dog_array.length);This is an extremely poor use of parseInt. The parseInt function works on strings, not numbers, so the expression would have to be evaluated, converted to a string, then parsed back to an integer. To convert the result of the expression to an integer, use Math.floor instead.


face_num=(isNaN(face_num))?0:face_num;This is completely unnecessary. Both operands in the multiplication above are numbers, so the result is guaranteed to be a finite number - it will never be NaN.


document.images['slide'].src = eval(dog_array[face_num]);The eval global function is unnecessary in probably 99% of all ECMAScript code, and is invariably a sign of poor quality or cluelessness on the part of the author. Harsh? Undoubtedly, but unfortunately true.

I'd write that code something like:


function isFunction(o) {return 'function' == typeof o;}
function isGenericObject(o) {return isObject(o) || isFunction(o);}
function isObject(o) {return !!o && ('object' == typeof o);}

Array.prototype.swap = function(i, j) {
var t = this[i]; this[i] = this[j]; this[j] = t;
};
Array.prototype.shuffle = function() {
var i = this.length; while(i--) {this.swap(i, Math.randomInt(i + 1));}
};
Math.randomInt = function(n) {
return Math.floor((Math.random() % 1) * n);
};

var faces = new (function(global) {
var dogs = ['images/faces/Darla100.jpg',
'images/faces/Beamer100.jpg',
'images/faces/Ebony100.jpg'],
current = 0,
interval = 2500,
length = dogs.length,
load, timer;

/* Check that necessary features
* are available before proceeding.
*/
if(!isGenericObject(global.Image) || !isGenericObject(global.setTimeout)
|| !isGenericObject(document.write)
|| !isGenericObject(document.images))
{return null;}

/* Randomise the order of the dogs array. */
dogs.shuffle();

document.write('<img alt="" src="' + dogs[0] + '" id="faces" name="faces"'
+' style="border-style: none; margin: 0 5px; vertical-align: top;">');

/* Prepare the preloading object. */
load = new Image();

function show() {
document.images.faces.src = dogs[current++];

/* If we've now moved through the entire set, */
if(length == current) {
/* reset the position, */
current = 0;
/* don't bother trying to preload any more, */
load = null;
/* and reshuffle the array (if you want to). */
/* dogs.shuffle(); */
}
if(load) {load.src = dogs[current];}

timer = setTimeout(show, interval);
};
(this.show = show).toString = function() {return 'faces.show();';};
})(this);

if(faces) {faces.show();}Several hours of sleep later: I've altered the code above somewhat, mainly to accomodate IE because it has strange notions that functions are actually objects :rolleyes:

I don't know what sort of images you're using, so testing the preloading mechanism properly may not be useful. The current scheme tries to load the image that's next in line, rather than all of them at once. If the images are of a reasonable size, the current 2500ms interval should be enough. If not, that part may need to be altered.

Using the code is relatively simple: place everything except the last line where you want the img to appear. You can place the last line pretty much anywhere you want after that point.

To reiterate: this may not fix your problem with regard to caching.

Mike

yardbird
06-30-2005, 04:19 PM
Well, cluelessness on the part of the author is not necessarily untrue. I have not done a lot of javascript and just took some scripts from a college class example and modified them.

I will try all of your suggestions. Thank-you so much.

link is:

http://www.shinydogs.org/petfinder/whoweare.php

mwinter
06-30-2005, 05:46 PM
Well, cluelessness on the part of the author is not necessarily untrue.There's nothing wrong with that, as long as it's just a temporary state. :) Everyone is clueless at some point, after all.

It doesn't help that there are many bad examples all over the Web, and authors that are new to the language don't have the experience to discern good from bad. For future reference, pretty much anything that includes the use of eval, or attempts to detect browsers, is bad. In the latter case, it's important to know what a browser is capable of doing, not what it is. Feature detection, as it's known, will work for all browsers - those that you know about, and those that you don't - and various versions of those browsers, which means you won't normally need to do anything to accomodate updates.


http://www.shinydogs.org/petfinder/whoweare.phpThe response headers seem to be fine, and my IE6 does cache images unless I forcefully refresh (F5) the document.

Mike

yardbird
06-30-2005, 06:23 PM
Glad to hear that not knowing js from birth is not a genetic defect. That would have been tough to fix. :-)

I ran into the same thing when reading the posts of others pertaining to CSS rollovers and flicker. The poster would say there was a flicker in IE, and several respondents would not see the flicker. But other posters could see it.

In one case, it was XP SP2 that made the difference, which is what I have. ( Hands tied behind my back at this point to avoid further comment on that subject. )

OK - - - I will keep looking.

mwinter
06-30-2005, 07:33 PM
Glad to hear that not knowing js from birth is not a genetic defect. That would have been tough to fix. :-):D


In one case, it was XP SP2 that made the difference, which is what I have.So do I. This machine should have all the current updates and fixe s that Microsoft have released. You might want to try searching or asking the Microsoft support newsgroups (http://support.microsoft.com/newsgroups/). You might find someone there more familiar with IE's caching quirks.

Good luck,
Mike