Preload images

C

CK

Hello everyone,

I am using an image browser to select images for a website.
Basically, it is a table showing the file name and the size, when you
move the mouse over one image, then it gets displayed in the lower
right corner.
The image browser works, has done so since ages, but I noticed
something which would explain the partly sluggish behaviour. When
using Firefox, I see one request per image and its all good, both in
the Firebug extention and in the access log of the Apache webserver
behind.
IE 6 also requests all the images, but then for each mouseover
requests the image again.

Well, it does not. Then I googled around for a bit and found a
gazillion hints, most of which said "have a function in the onload
Event-Handler and it will work".
So I wrote a quick and dirty function which simply requests the
images onLoad, figuring that might help.

It does not. So, is this really an IE 6 issue or is there something I
can do about this to make it work?
--
Claus Dragon <[email protected]>
=(UDIC)=
d++ e++ T--
K1!2!3!456!7!S a29
"Coffee is a mocker. So, I am going to mock."

- Me, lately.
 
E

Erwin Moller

CK schreef:
Hello everyone,

I am using an image browser to select images for a website.
Basically, it is a table showing the file name and the size, when you
move the mouse over one image, then it gets displayed in the lower
right corner.
The image browser works, has done so since ages, but I noticed
something which would explain the partly sluggish behaviour. When
using Firefox, I see one request per image and its all good, both in
the Firebug extention and in the access log of the Apache webserver
behind.
IE 6 also requests all the images, but then for each mouseover
requests the image again.

Well, it does not. Then I googled around for a bit and found a
gazillion hints, most of which said "have a function in the onload
Event-Handler and it will work".
So I wrote a quick and dirty function which simply requests the
images onLoad, figuring that might help.

It does not. So, is this really an IE 6 issue or is there something I
can do about this to make it work?
--
Claus Dragon <[email protected]>
=(UDIC)=
d++ e++ T--
K1!2!3!456!7!S a29
"Coffee is a mocker. So, I am going to mock."

- Me, lately.

Hi,

Could you show us your code for preloading, and for displaying?

Regards,
Erwin Moller
 
S

SAM

CK a écrit :
Hello everyone,

I am using an image browser to select images for a website.
Basically, it is a table showing the file name and the size, when you
move the mouse over one image, then it gets displayed in the lower
right corner.

Is it something like :

<p id="smallImgs">
<img src="photo_1.jpg" onmouseover"viewer.src=this.src" alt="">
<img src="photo_2.jpg" onmouseover"viewer.src=this.src" alt="">
<img src="photo_2.jpg" onmouseover"viewer.src=this.src" alt="">
</p>
<img name="viewer" src="empty.gif" alt=="">

Or do you use thumbnalis and associated big images ?
IE 6 also requests all the images, but then for each mouseover
requests the image again.

Idea for a gallery of images :

<script type="text/javascript">

var P = ['dod','cat','cow'], // array of images to display later
fold = 'album_1/', // folder of images
k = 0,
I = [] ;
function cacheImg() { // put in cache paths of images
if(k<P.length) {
var F = true;
I[k] = new Image();
// if possible force the image in the cache
if('object' != typeof I[k].onload) { F=!F; I[k].onload = cacheImg; }
I[k].src = fold + P[k] + '.jpg';
k++
if(F) cacheImg();
}
else reveal();
}
function reveal() {
document.getElementById('wait').style.display='none';
document.getElementById('album').style.display='block';
}
function browse(num) {
document.images['viewer'].src = I[num].src;
}

window.onload = cacheImg;

</script>
</head>
<body>
<p id="wait">Please wait images loading <img src="wait.gif" alt=""></p>
<p style="display:none" id="album">
<a href="javascript:browse(0)">view 1</a>
<a href="javascript:browse(1)">view 2</a>
<a href="javascript:browse(2)">view 3</a>
</p>
<img name="viewer" src="vide.gif" alt="">
 
S

Snorik

Hello,

sure, here is the Javascript code:

var freeze = 0;
function datacapture_get_content()
{
var data = '';
var calloutForm =
eval(window.opener.top.getDCFrame(window.opener).formframe.document.dcreditForm);
if (!calloutForm)
{
alert('Fatal callout error. Did you close the datacapture
window?');
}
var calloutElementFound = false;
for ( i = 0 ; i < calloutForm.elements.length ; i++ )
{
if (calloutForm.elements.name == 'catalog_update_content/
catalog_thumbnail_FBA')
{
data = calloutForm.elements.value ;
calloutElementFound = true ;
break;
}
}
return data;
}

function datacapture_callback( data )
{
var calloutForm =
eval(window.opener.top.getDCFrame(window.opener).formframe.document.dcreditForm);
if (!calloutForm)
{
alert('Fatal callout error. Did you close the datacapture
window?');
}
var calloutElementFound = false;
for ( i = 0 ; i < calloutForm.elements.length ; i++ )
{
if (calloutForm.elements.name == 'catalog_update_content/
catalog_thumbnail_FBA')
{
calloutForm.elements.value = data ;
calloutElementFound = true ;
break;
}
}
if(opener.top.datacapture) {
opener.top.datacapture.refreshForm();
}
self.close();
}

function set_content()
{
var fba = document.form.fba.value;
if (!fba)
{
alert('Please select one file');
}
else
{
datacapture_callback(fba);
}

}
function set_dir( data )
{
freeze = 1 ;
document.form.dir.value = data;
document.form.files_view.value = '0';
document.form.submit();

}
function set_file( value, data )
{
document.forms[0].fba.value = value;
if (freeze == 0)
{
freeze = 1 ;
}
else
{
freeze = 0 ;
document.images['imageboard'].src = ts_image[data].src;
document.images['imageboard'].width = ts_image[data].width;
document.images['imageboard'].height = ts_image[data].height;
document.forms[0].name.value = ts_image[data].name;
document.forms[0].size.value = ts_image[data].size;
}
}

function show_image( data ) {
if (freeze == 0) {
document.images['imageboard'].src = ts_image[data].src;
document.images['imageboard'].width = ts_image[data].width;
document.images['imageboard'].height = ts_image[data].height;
document.forms[0].name.value = ts_image[data].name;
document.forms[0].size.value = ts_image[data].size;
}
}

function show_no_image(data) {
if (freeze == 0) {
document.images['imageboard'].src = '/iw/images/c.gif';
document.images['imageboard'].width = '';
document.images['imageboard'].height = '';
document.forms[0].name.value = ts_image[data].name;
document.forms[0].size.value = ts_image[data].size;
}
}

function set_view( data )
{
document.form.view.value = data;
document.form.dir.value = '';
document.form.files_view.value = '0';
document.form.submit();

}
function set_file_view( data )
{
document.form.files_view.value = data;
document.form.submit();
}

ts_image = new Array( 13 );
ts_image[12] = new Image(300,199);
ts_image[12].src = '/images_path/image1.jpg';
ts_image[12].width = '300';
ts_image[12].height = '199';
ts_image[12].name = 'filename : image1.jpg';
ts_image[12].size = 'filesize : 612 x 406';
ts_image[10] = new Image(102,72);
ts_image[10].src = '/images_path/image2.jpg';
ts_image[10].width = '102';
ts_image[10].height = '72';
ts_image[10].name = 'filename : image2.jpg';
ts_image[10].size = 'filesize : 102 x 72';

// removed additional entries, I think you get the picture


// basically redundant function for the body tag onLoad event trigger,
to try out whether that helps with IE 6
//it does not really help. Yes, I know, it simply doubles the
requests, as the images are already loaded, at least for FireFox.
function loadImages(){
images = new Array( 13 );
images[12] = '/images_path/image1.jpg';
images[10] = '/images_path/image2.jpg';
//again, additional values removed
}

<!-- here is the code in the body -->

<body onload="loadImages()">
<!-- [...] -->

<!-- the actual table: -->

<table class="heading" height="25" border="0" width="100%">
<tr>
<td class="heading-title">Image browser</td>
<td class="heading-user" align="right">user:&nbsp <i>user</i></td>
</tr>
</table>
<form method="get" id="form" name="form">
<div style="width:600px; height:22px; border:1px solid #840; border-
bottom: 0px; background-color: #eeeeee; margin-left:1em; margin-top:
0.8em;">
&nbsp;
<font color='#666666' style='font-size:11px'>local:&nbsp;</font>
<!-- woops, here is a table start missing -->
<tr style='background-color: #ddeeff;' >
<td align='left' width='5px'>
<img src="/file_images/img_file.gif" alt="dir" height="15"
border="0" />
</td>
<td>
<a href='javascript:set_file("/images_path/image1.jpg", "0");'
onDbClick='set_content();' onmouseover='show_image( 0 );'>
image1.jpg
</a>
</td>
<td style='font-size: 11px;'>
(277 x 184)
</td>
<td style=' font-size: 11px;'>
15 kb
</td>
</tr>

<!-- and so on ... -->

I have removed some of the values in order not to have a boring list
of array entries.
Is there anything in there which could possibly make IE not use the
cached images?

Thanks for your time,

Claus
 
S

Snorik

CK a écrit :



Is it something like :

<p id="smallImgs">
<img src="photo_1.jpg" onmouseover"viewer.src=this.src" alt="">
<img src="photo_2.jpg" onmouseover"viewer.src=this.src" alt="">
<img src="photo_2.jpg" onmouseover"viewer.src=this.src" alt="">
</p>
<img name="viewer" src="empty.gif" alt=="">

Or do you use thumbnalis and associated big images ?

Perl::ImageMagick creates thumbnails to fit into the image area.

Idea for a gallery of images :

<script type="text/javascript">

var P = ['dod','cat','cow'], // array of images to display later
fold = 'album_1/', // folder of images
k = 0,
I = [] ;
function cacheImg() { // put in cache paths of images
if(k<P.length) {
var F = true;
I[k] = new Image();
// if possible force the image in the cache
if('object' != typeof I[k].onload) { F=!F; I[k].onload = cacheImg; }
I[k].src = fold + P[k] + '.jpg';
k++
if(F) cacheImg();
}
else reveal();}

How does this work? If the image in question is not in the cache
array, then load the object on load by the function? I already use an
array to store the images, two in fact (one being redundant, see other
post).

Regards,
Claus
 
S

SAM

Snorik a écrit :
Idea for a gallery of images :

<script type="text/javascript">

var P = ['dod','cat','cow'], // array of images to display later
fold = 'album_1/', // folder of images
k = 0,
I = [] ;
function cacheImg() { // put in cache paths of images
if(k<P.length) {
var F = true;
I[k] = new Image();
// if possible force the image in the cache
if('object' != typeof I[k].onload) { F=!F; I[k].onload = cacheImg; }
I[k].src = fold + P[k] + '.jpg';
k++
if(F) cacheImg();
}
else reveal();}

How does this work? If the image in question is not in the cache

doing a JS in the head like

var a = new Image(); a.src='img_1.jpg';
var b = new Image(); b.src='img_2.jpg';

both images are supposed to be sent in the cache


If they are not yet
(because you dind't leave time to time or any other reason),
no importance.
Calling the image by its JS src will load the right image,
a.src being only the path to the image (on server).

But, on next call of a.src,
this time we surely get the image from cache.
 
H

Henry

On Apr 4, 1:21 pm, SAM wrote:
doing a JS in the head like

var a = new Image(); a.src='img_1.jpg';
var b = new Image(); b.src='img_2.jpg';

both images are supposed to be sent in the cache

Says who?
If they are not yet
(because you dind't leave time to time or any other reason),
no importance.
Calling the image by its JS src will load the right image,
a.src being only the path to the image (on server).

But, on next call of a.src,

You are disregarding the influence of HTTP caching (and caching
influencing) headers and browser configuration. If the browser is
configured to re-retrieved for each request that is what it will do,
and if the HTTP headers assert that the image is not to be cached the
odds are good that it will not be, and if they assert that any
previously cached resource has expired it should be re-retrieved
regardless of whether it is in the cache or not.
 
S

SAM

Henry a écrit :
On Apr 4, 1:21 pm, SAM wrote:


Says who?

Not me.
(Rarely I've seen that really working on 1srt pass)
You are disregarding the influence of HTTP caching

Yes, absolutely, and it's a good remark.
I hope all is OK to do what this JS is supposed to do.

I can't fix all the configurations from my chair :)
 
S

Snorik

Snorik a écrit :


On 4 Apr., 10:16, SAM <[email protected]>
wrote:
Idea for a gallery of images :
<script type="text/javascript">
var P = ['dod','cat','cow'], // array of images to display later
fold = 'album_1/', // folder of images
k = 0,
I = [] ;
function cacheImg() { // put in cache paths of images
if(k<P.length) {
var F = true;
I[k] = new Image();
// if possible force the image in the cache
if('object' != typeof I[k].onload) { F=!F; I[k].onload = cacheImg; }
I[k].src = fold + P[k] + '.jpg';
k++
if(F) cacheImg();
}
else reveal();}
How does this work? If the image in question is not in the cache

doing a JS in the head like

var a = new Image(); a.src='img_1.jpg';
var b = new Image(); b.src='img_2.jpg';

both images are supposed to be sent in the cache

Ok, but am I not doing that already via the array(s)?
If they are not yet
(because you dind't leave time to time or any other reason),
no importance.
Calling the image by its JS src will load the right image,
a.src being only the path to the image (on server).

OK.
 
S

Snorik

You are disregarding the influence of HTTP caching (and caching
influencing) headers and browser configuration. If the browser is
configured to re-retrieved for each request that is what it will do,
and if the HTTP headers assert that the image is not to be cached the
odds are good that it will not be, and if they assert that any
previously cached resource has expired it should be re-retrieved
regardless of whether it is in the cache or not.

Silly question but where do I see that? Live HTTP headers does not
show any expiry-date, at least none I can recognize...
Also, where in that trice-%&§! IE can I toggle that?
 
S

SAM

Snorik a écrit :
Ok, but am I not doing that already via the array(s)?

I'm a little lost in your fat code ;-)

Where are the src of new images ?

here ? :

ts_image = new Array( 13 );
ts_image[12] = new Image(300,199);
ts_image[12].src = '/images_path/image1.jpg';
ts_image[12].width = '300';
ts_image[12].height = '199';
ts_image[12].name = 'filename : image1.jpg';
ts_image[12].size = 'filesize : 612 x 406';

what could be the use of width, height, size ?


or here ? :

function loadImages(){
images = new Array( 13 );
images[12] = '/images_path/image1.jpg';
images[10] = '/images_path/image2.jpg';
//again, additional values removed
}
where I see no 'src' ...


Try :

var images = new Array(); // except if you use it in a loop
// you don't need the number of images

function loadImages(){
images[12] = new Image();
images[12].src = '/images_path/image1.jpg';
images[11] = new Image();
images[11].src = '/images_path/image2.jpg';
//again, additional values removed
}

and this function could be good for all navigators


Your biggest problem is that you want to change images on a mouseover
and in most of cases the new image to display is still on the server, so
user will have to be patient.
The second point is that the browser, on each call to one image, will go
to see on server if the image to display is the same as this in its cache.

Then ... I do not understand the utility of this funtion 'loadImages'
and its array 'images' when to display a new image you use the array
'ts_image' here :

function show_image( data ) {
if (freeze == 0) {
document.images['imageboard'].src = ts_image[data].src;
document.forms[0].name.value = ts_image[data].name;
document.forms[0].size.value = ts_image[data].size;
}
 
C

CK

Snorik a écrit :
Ok, but am I not doing that already via the array(s)?

I'm a little lost in your fat code ;-)

Where are the src of new images ?

here ? :

ts_image = new Array( 13 );
ts_image[12] = new Image(300,199);
ts_image[12].src = '/images_path/image1.jpg';
ts_image[12].width = '300';
ts_image[12].height = '199';
ts_image[12].name = 'filename : image1.jpg';
ts_image[12].size = 'filesize : 612 x 406';

what could be the use of width, height, size ?

Those are being used for ImageMagick.
or here ? :

function loadImages(){
images = new Array( 13 );
images[12] = '/images_path/image1.jpg';
images[10] = '/images_path/image2.jpg';
//again, additional values removed
}
where I see no 'src' ...

Ok, my mistake, completely forgot about that.
Try :

var images = new Array(); // except if you use it in a loop
// you don't need the number of images

function loadImages(){
images[12] = new Image();
images[12].src = '/images_path/image1.jpg';
images[11] = new Image();
images[11].src = '/images_path/image2.jpg';
//again, additional values removed
}

and this function could be good for all navigators

Ok, I will try that out and post some results.
Your biggest problem is that you want to change images on a mouseover
and in most of cases the new image to display is still on the server, so
user will have to be patient.
The second point is that the browser, on each call to one image, will go
to see on server if the image to display is the same as this in its cache.

Then ... I do not understand the utility of this funtion 'loadImages'
and its array 'images' when to display a new image you use the array
'ts_image' here :

I had just added the loadImages() function in order to check whether
taking advantage of the onload event handler had any impact.

--
Claus Dragon <[email protected]>
=(UDIC)=
d++ e++ T--
K1!2!3!456!7!S a29
"Coffee is a mocker. So, I am going to mock."

- Me, lately.
 
S

SAM

CK a écrit :
I had just added the loadImages() function in order to check whether
taking advantage of the onload event handler had any impact.

I didn't see in details all your lines of code but if you don't call the
array 'images' (foo.src = images[number].src) there is no advantage than
to give some more work to the browser.

Difference I see between to give directly the array of new images (and
their src) in the head and by a function on loading (after loaded) is :
- in head it is supposed that new images (or at least their path : src)
are put in cache "before" full loading
- body onload : caching only "after" the page is loaded (displayed)
but ... as soon as user begins to click the page I think this
'loadImages' is stopped (or at least paused)

The first way (if it works : images loaded and in cache) is, on my idea,
not good for user who will can have to wait with a white screen all big
images. (usually only paths are memorized for a possible re-using and
that takes no time)
The 2nd allows the page to load normally.

In my youngness most of browsers accepted the function 'onload'
attributed to images (and by the fact attributed to JS new images).
With this feature it was possible to be sure to get them in cache (if
correctly fixed HTTP headers and so on)

var Imgs = new Array();
var fold = 'album_1/';
var Views = new Array(13);
var n = 0;
function postLoad() {
if(n < Views.length) {
Imgs[n] = new Image();
Imgs[n].onload = postLoad; // when img 'n' loaded go to load next one
Ims[n].src = fold + 'photo_' + n + '.jpg';
n++
}
}

Seems to do no more work with my Safari, Opera and IE6
( image.onload is not a function for them)
Only my Fx supports that.



Possibility (not tested) to post-load images :

CSS :
=====
#stock { position: absolute; margin-left: -2000px; width: 1500px }
#stock img { position: absolute; top:0; left: 0;}

JS :
====
var Imgs = new Array(),
num = 13,
fold = 'album_1/';
window.onload = function() {
for(var i=0; i<num; i++) {
Imgs[n] = new Image();
Imgs[n].src = fold+n+'.jpg';
createImg(n).src = Imgs[n].src;
}
}
function createImg(n) {
var I = document.createElement('IMG');
I.id = 'S_'+n;
document.getElementById('stock').appendChild(I);
return I;
}
function showImg(num) {
var viewScreen = document.getElementById('viewer');
if(document.getElementById('S_'+num)) {
var I = document.getElementById('S_'+num);
var f = document.forms[0];
viewScreen.src = I.src;
f[0].value = I.width;
f[1].value = I.height;
}
else
viewScreen.src = Imgs[n].src;
}

html :
======
<div id="stock"></div>
<p><a href="javascript:showImg(0)">view 1</a>
<a href="javascript:showImg(1)">view 2</a>
<a href="javascript:showImg(2)">view 3</a></p>
<form>
Image width: <input>, image height: <input>
<img id="viewer" src="empty.gif" alt="">
</form>

With a little bit of luck perhaps that could +/- work ?
 
S

Snorik

CK a écrit :


I had just added the loadImages() function in order to check whether
taking advantage of the onload event handler had any impact.

I didn't see in details all your lines of code but if you don't call the
array 'images' (foo.src = images[number].src) there is no advantage than
to give some more work to the browser.

Ok, I changed that. Now there is only one array of images which looks
like the following:


function loadImages()
{
[...]
ts_image = new Array( 13 );
ts_image[12] = new Image(300,199);
ts_image[12].src = '/path/image';
ts_image[12].width = '300';
ts_image[12].height = '199';
ts_image[12].name = 'filename : image';
ts_image[12].size = 'filesize : 612 x 406';
[other values removed due to avoid clutter]
}

function show_image( data ) {
if (freeze == 0) {
document.images['imageboard'].src = ts_image[data].src;
document.images['imageboard'].width = ts_image[data].width;
document.images['imageboard'].height = ts_image[data].height;
document.forms[0].name.value = ts_image[data].name;
document.forms[0].size.value = ts_image[data].size;
}
}

one of the list items:

<tr >
<td align='left' width='5px'>
<img src="img_file.gif" alt="dir" height="15" border="0" />
</td><td>
<a href='javascript:set_file("path/image.jpg", "11");'
onDbClick='set_content();' onmouseover='show_image( 11 );'>
image
</a>
</td>
<td style='font-size: 11px;'>

(277 x 184)
</td>
<td style=' font-size: 11px;'>
15 kb
</td>
</tr>


The img tag where the images are being shown:

<td valign='top' align='center'>
<img name='imageboard' width='300' height='210' border='0' src='path/
image'>
Difference I see between to give directly the array of new images (and
their src) in the head and by a function on loading (after loaded) is :
- in head it is supposed that new images (or at least their path : src)
are put in cache "before" full loading
- body onload : caching only "after" the page is loaded (displayed)
but ... as soon as user begins to click the page I think this
'loadImages' is stopped (or at least paused)

The first way (if it works : images loaded and in cache) is, on my idea,
not good for user who will can have to wait with a white screen all big
images. (usually only paths are memorized for a possible re-using and
that takes no time)
The 2nd allows the page to load normally.

Ok, the second approach sounds more reasonable anyways.

*snip*
Seems to do no more work with my Safari, Opera and IE6
( image.onload is not a function for them)
Only my Fx supports that.

It is working in Ffx anyways, its just IE which is getting on my
nerves.

Still does not work for IE. I also tried to use the document.images[n]
object, figuring that those images should be in cache as they are in
the document which is completely loaded, but it is a bit hard to find
out which image of my array lands in what position of that array. Is
there an easy way to check this, apart from iterating over the
document.images (for i=0, ...) {if document.images..src =
ts_image.src } ?


Cheers.
 
T

Thomas 'PointedEars' Lahn

Snorik said:
CK a écrit :
I had just added the loadImages() function in order to check whether
taking advantage of the onload event handler had any impact.
I didn't see in details all your lines of code but if you don't call the
array 'images' (foo.src = images[number].src) there is no advantage than
to give some more work to the browser.

Ok, I changed that. Now there is only one array of images which looks
like the following:

function loadImages()
{
[...]
ts_image = new Array( 13 );

Since you don't appear to use ts_image.length, the `13' argument is
unnecessary and potentially harmful (not because it's this particular number).
ts_image[12] = new Image(300,199);

The arguments are unnecessary.
ts_image[12].src = '/path/image';
OK.

ts_image[12].width = '300';
ts_image[12].height = '199';

Those properties expect number values, not strings. Besides, they would
have been set already with the constructor arguments, which is what they are
for.
ts_image[12].name = 'filename : image';

`Image' objects are host objects, they do not need to be supported, and if
they are, they do not need to support the augmentation with properties.

`Image' objects don't have a `name' property by default, and even if they do
implement the HTMLImageElement interface of W3C DOM Level 2 HTML, the `name'
property would require a NAME value, which must not contain whitespace or `:'.
ts_image[12].size = 'filesize : 612 x 406';

Same here. Besides, the image dimensions are _not_ the file size.

You should use something like the following:

function getImage(s, fLoad, fError)
{
var img = new Image();
img.src = s;

if (typeof fLoad == "function"
&& typeof img.onload != "undefined")
{
img.onload = fLoad;
}

if (typeof fError == "function"
&& typeof img.onerror != "undefined")
{
img.onerror = fError;
}
}

var ts_image = new Array(
getImage('/path/image')
);

(or

var ts_image = new Array();
ts_image[12] = getImage('/path/image');

but there is little point in that although it works.)

The rest can follow from the `width', `height', and `src' properties that
the object has already; you do not have to duplicate that information, but
you can write a wrapper object that allows it to be retrieved easily in the
desired form:

function MyImage(s)
{
this.setImage(s);
}

MyImage.prototype = {
constructor: MyImage,

setImage: function(s) {
this.data = getImage(s);
this.filename = s;
},

getNameStr: function() {
return "filename: image";
},

getDimensions: function() {
return "dimensions: " + this.data.width + " x " + this.data.height;
}
};

var ts_image = new Array(
new MyImage('/path/image')
);

// note the timing issue
window.alert(ts_image[0].getDimensions);
[...]
function show_image( data ) {
if (freeze == 0) {

Where does `freeze' come from? Avoid global variables.
document.images['imageboard'].src = ts_image[data].src;
document.images['imageboard'].width = ts_image[data].width;
document.images['imageboard'].height = ts_image[data].height;

This is quite inefficient. Consider this:

var imgTarget = document.images['imageboard'];
var imgSource = ts_image[data];

imgTarget.src = imgSource.src;
imgTarget.width = imgSource.width;
imgTarget.height = imgSource.height;

One could even consider

with (imgSource)
{
imgTarget.src = src;
imgTarget.width = width;
imgTarget.height = height;
}
document.forms[0].name.value = ts_image[data].name;
document.forms[0].size.value = ts_image[data].size;

Same here. You should avoid such reference worms, they are not only
inefficient, but also error-prone and hard to maintain.
[...] }
}

one of the list items:

[reformatted; use spaces for indentation, not tabs]
<tr>
<td align='left' width='5px'>
<img src="img_file.gif" alt="dir" height="15" border="0" />
^
It can be only either HTML or XHTML. I suggest you use the former, also
because you use camel-cased attribute names already which is not allowed in
XHTML.
</td><td>
<a href='javascript:set_file("path/image.jpg", "11");'
onDbClick='set_content();' onmouseover='show_image( 11 );'> ^^^
Typo.

image

Avoid whitespace after inner start tags and before inner end tags, it is not
uniformly displayed.

If a widget works only with enabled script-support, you should generate it
with scripting to save other users and yourself the hassle of dealing with a
widget "not working":

<script type="text/javascript">
document.write(
'<a href=\'javascript:set_file('
+ '"path/image.jpg", "11");\' ondblclick="set_content();"'
+ ' onmouseover="show_image(11);">image<\/a>'
);
</script>

That said, you should avoid such widgets in the first place. For example, a
submit button can provide for functionality that degrades gracefully here.
[...]
The img tag where the images are being shown:

There are no "img tags". There are `img' elements said:


HTH

PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas said:
[...]
var ts_image = new Array(
new MyImage('/path/image')
);

// note the timing issue
window.alert(ts_image[0].getDimensions);

Race conditions aside, don't forget to call it :)

window.alert(ts_image[0].getDimensions());


PointedEars
 
S

SAM

Snorik a écrit :
Ok, the second approach sounds more reasonable anyways.


It is working in Ffx anyways, its just IE which is getting on my
nerves.

With IE you can try to load each image at place of another one (this
last one being positioned outside ot the window)


HTML :
======
<img src="#" style="position:absolute;margin-left:-2000px;left:-2000px"
name="IE" alt="false image" onload="loadIncache()">
<h2 style="color:red">Images loading : <span id="wait"></span></h2>

JS :
====
var idx = 0;
function loadInCache() {
if(idx < ts_image.length) {
document.IE.src = ts_image[idx].src;
document.getElementById('wait').innerHTML += 'X';
idx++
}
else
document.getElementById('wait').innerHTML = 'no more image';
}
window.onload = function() {
loadImages();
loadInCache();
}




Absolutely not tested !
In fact that works with Safari
but I've got a problem : my IE6 doesn't see : window.onload :-(
 
C

CK

Words to the wise, Thomas 'PointedEars' Lahn <[email protected]>
wrote:
*snip before*

Ok, thanks for the hints and pointers on that part so far, I will use
your suggestions.
[reformatted; use spaces for indentation, not tabs]
<tr>
<td align='left' width='5px'>
<img src="img_file.gif" alt="dir" height="15" border="0" />
^
It can be only either HTML or XHTML. I suggest you use the former, also
because you use camel-cased attribute names already which is not allowed in
XHTML.

What do you mean with "camel-cased"?

*snip further two suggestions which will be implemented*
If a widget works only with enabled script-support, you should generate it
with scripting to save other users and yourself the hassle of dealing with a
widget "not working":

Could you please explain this a bit further?

*snip code*
That said, you should avoid such widgets in the first place. For example, a
submit button can provide for functionality that degrades gracefully here.

Oh, there is a submit button there for submitting the selection. The
whole problem is getting IE not to request each image for each
mouseover.

Is there an AJAX way to check when a request is currently on its way
and until that is finished not execute the next request on a special
event handler (mouseover in this case)?
[...]
The img tag where the images are being shown:

There are no "img tags". There are `img' elements, and <img ...> start tags.

Ok, I fell into that pit, serves me right, I guess.

Thanks for your help.
--
Claus Dragon <[email protected]>
=(UDIC)=
d++ e++ T--
K1!2!3!456!7!S a29
"Coffee is a mocker. So, I am going to mock."

- Me, lately.
 
S

SAM

Thomas 'PointedEars' Lahn a écrit :
You should use something like the following:

function getImage(s, fLoad, fError)
{
var img = new Image();
img.src = s;

if (typeof fLoad == "function"
&& typeof img.onload != "undefined")

My Safari thinks it's an 'object'
My Firefox thinks it's 'undefined'
{
img.onload = fLoad;

That works with my Firefox(*) and not with my Safari

(*) if typeof img.onload != 'object'
 
T

Thomas 'PointedEars' Lahn

CK said:
Words to the wise, Thomas 'PointedEars' Lahn <[email protected]>
wrote:
*snip before*

Ok, thanks for the hints and pointers on that part so far, I will use
your suggestions.

You're welcome.
[reformatted; use spaces for indentation, not tabs]
<tr>
<td align='left' width='5px'>
<img src="img_file.gif" alt="dir" height="15" border="0" />
^
It can be only either HTML or XHTML. I suggest you use the former, also
because you use camel-cased attribute names already which is not allowed in
XHTML.

What do you mean with "camel-cased"?

In this case: mixing uppercase and lowercase characters.

http://en.wikipedia.org/wiki/CamelCase

You should use only lowercase letters for element type/element/attribute
names and IDs instead, not only because XHTML demands it for element types
and attribute names (and so either it is a requirement for Valid/working
markup, or a future transition will be easier), but also because turns out
to be easier to maintain [think of search and replace, and of DOM access],
and to be better compressible (lowercase characters have a greater
probability than uppercase characters in a standard latin text).
Could you please explain this a bit further?

Gladly.

Users of an environment where client-side script support is not available
will complain to you (or your customer who owns the site) or silently go
away because either nothing happens if a widget is activated or in your case
it may very well cause an error message then. If they complain, you (or
your customer) will have to deal with the complaints (which can affect your
reputation in a negative way). In any case, you (or your customer) will
have to deal with your shrinking/comparably small user base (you'll/they'll
ask yourself/themselves: Why are some of my competitors this much more
successful?)

It is a key feature of a good Web site/application, and a legal requirement
in some environments/countries, to be accessible, to degrade gracefully if a
used technology is not available, including client-side scripting. One
important reason for that, but by far not the only one, is that studies have
shown people with disabilities to use the Internet (and the Web)
proportionally more than other people -- guess why.
Oh, there is a submit button there for submitting the selection. The
whole problem is getting IE not to request each image for each
mouseover.

Pardon, I just jumped into the thread, observing the (to me) obvious
mistakes in your code.

The problem you describe exists with other user agents as well, and
preloading as you are trying can help here, but it does not have to. The
cache of the user's user agent is solely under the control of the user,
not the Web developer. In the worst case, the image will be downloaded
twice at least. This is not to recommend foregoing the idea completely,
you should just be aware of it.
Is there an AJAX way to check when a request is currently on its way
and until that is finished not execute the next request on a special
event handler (mouseover in this case)?

("AJAX" is a misnomer. s/AJAX/XMLHttpRequest (XHR)/g)

Not really. You would have to request the data through XHR then, and then
you would have the problem to use the response body to generate an image
(`javascript:' and `data:' URIs can help out here, but they do not have to).


Your (quite interesting) .sig is a bit long, try to reduce it to 4 lines
(not counting the delimiter). Also, the delimiter is broken; it has to be
"-- <CR><LF>".

I am a bit confused about your "From" header, probably I'm not the only one.
It is better to post only under one name in Usenet in order to avoid
confusion and to be recognized, preferably your real one (as you can see,
the nickname can also be included easily).


Regards,

PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top