Refreshing multiple images

J

John Dann

A simple question but an extended post I'm afraid! I need to refine
some JS code to refresh two or more images in a web page at timed but
different intervals, but without refreshing the page as a whole. I can
program - mostly in .Net - but rarely use JS hence this post for
specifically JS advice please.

I've dug out some JS code to do what I need from around the web, but I
want to understand what's going on and also to make the code as simple
and concise as possible. So let me list the code and then maybe I can
ask some questions:

First, I see that it's good practice for JS to refer to an image by a
name, so the HTML that declares the image on the web page has a name
property, eg:

<img border="0" src="image1.gif" name="image1"/>

The actual JS seems to involve two parts: a function block placed in
the header and then a call to the function placed in the onload
attribute of the <body> tag. Let me ask about these two parts
separately.

1. The function definition:

At present I'm using some copied code in the HTML header that says:

<script language="JavaScript">
function refreshIt() {
if (!document.images) return;
document.images['image1'].src = 'image1.gif?' + Math.random();
setTimeout('refreshIt()',60000); // refresh every 60 secs
}
<script>

AIUI the 'if (!document.images) return;' segment is just for
compatibility with older browsers so can presumably stay as is.

Then the Math.random is apparently just a device that happens to cause
a new copy of the image to be downloaded from the server. I guess I
don't need to know why, it's presumably just a handy quirk of JS. But
2 questions on this line of code:

I wondered if it was better JS style these days to say
document.images.image1.src = ... (Is this correct?)

What's the question mark a placeholder for?

Now the setTimeout line. This looks a bit odd to me, referring to the
function within the function itself. But presumably it's correct? (The
60000 is obviously the refresh time - no problem - though why is it
repeated in the body tag attribute - see below?).

2. The body code:

<body onLoad=" setTimeout('refreshIt()',60000)">

I'm not sure exactly what this is doing - presumably it initialises
the refresh cycle. Well I could undertsand what it was doing if the
setTimeout wasn't also included in the function definition - it's the
duplication I'm unclear about.

Finally, as per my introduction, what I really need is a function that
will manage the refreshing of two or more images at different
intervals. So I'm guessing that the function could be written as:

function refreshIt(imagename, refreshinterval) {...

with an appropriate string and long integer for imagename and
refreshinterval respectively. But I'm not sure what the exact syntax
thereafter might be, nor how the argument for the onLoad event in the
body tag would be coded for two or more images.

Any comments etc gratefully received, especially for making the code
as simple and concise as possible.
 
E

Evertjan.

John Dann wrote on 12 jul 2007 in comp.lang.javascript:
A simple question

How do you know it is simple?
but an extended post I'm afraid! I need to refine [....]

First, I see that it's good practice for JS to refer to an image by a
name, so the HTML that declares the image on the web page has a name
property, eg:

<img border="0" src="image1.gif" name="image1"/>

use > in stead of />

Another just as good practice is to use id in stead of name:

<imgsrc='image1.gif' id='image1'>
....
document.getElementById('image1').src='image1.gif?' + ....

[......]
<script language="JavaScript">

That is ancient, use:

function refreshIt() {
if (!document.images) return;

Whay older browsers you expect would need that on the web?
document.images['image1'].src = 'image1.gif?' + Math.random();

Seems all right, I would prefer to add time as a number, it should need
less overhead and is truly nonrepeating

document.images['image1'].src = 'image1.gif?' + +new Date();


setTimeout('refreshIt()',60000); // refresh every 60 secs
}
<script>

AIUI the 'if (!document.images) return;' segment is just for
compatibility with older browsers so can presumably stay as is.

Ancient. I would leave it out.
And I would preferably use getElementById(),
but that is my personal preference.
Then the Math.random is apparently just a device that happens to cause
a new copy of the image to be downloaded from the server. I guess I
don't need to know why, it's presumably just a handy quirk of JS.

Wrong presumption, it has nothing to do with javascript.
And it always is better too know why:
Your browser tries to cache an image by it's url,
so refreshing only works reliably if the url is different every time.
But 2 questions on this line of code:

I wondered if it was better JS style these days to say
document.images.image1.src = ... (Is this correct?)

Not better, it is equivalent, see above.
What's the question mark a placeholder for?

It is not. It is part of the url dividing the web address part from the
querystring part. Try on an empty test.html:

<script type='text/javascript'>
alert( 'image1.gif?' + +new Date(); );
Now the setTimeout line. This looks a bit odd to me, referring to the
function within the function itself. But presumably it's correct? (The
60000 is obviously the refresh time - no problem - though why is it
repeated in the body tag attribute - see below?).

setTimeout() only works once.
setInterval() would work repeatedly.
2. The body code:

<body onLoad=" setTimeout('refreshIt()',60000)">

I'm not sure exactly what this is doing - presumably it initialises
the refresh cycle. Well I could undertsand what it was doing if the
setTimeout wasn't also included in the function definition - it's the
duplication I'm unclear about.

It delays the first refresh cycle, a good but really unneccessary delay.
Finally, as per my introduction, what I really need is a function that
will manage the refreshing of two or more images at different
intervals. So I'm guessing that the function could be written as:

function refreshIt(imagename, refreshinterval) {...

Why at different intervals? Well, try:

================

<head>
<script type='text/javascript'>
function refresh1() {
document.getElementById('image1').src='image1.gif?' + +new Date();
setTimeout('refresh2()',60000); // refresh every 120 !!! secs
};

function refresh2() {
document.getElementById('image2').src='image1.gif?' + +new Date();
setTimeout('refresh1()',60000); // refresh every 120 !!! secs
};
<script>
</head>

<body onLoad = refresh1()'>
<imgsrc='image1.gif' id='image1'>
<br>
<imgsrc='image2.gif' id='image2'>

=================

Without different intervals:

================

<head>
<script type='text/javascript'>
function refresh() {
document.getElementById('image1').src='image1.gif?' + +new Date();
document.getElementById('image2').src='image1.gif?' + +new Date();
setTimeout('refresh2()',60000); // refresh every 60 secs
};
<script>
</head>

<body onLoad = refresh()'>
<imgsrc='image1.gif' id='image1'>
<br>
<imgsrc='image2.gif' id='image2'>

=================

Or, if you have 20 images:

function refresh() {
var d = +new Date();
for (var i=1;i<=20;i++)
document.getElementById('image'+i).src='image'+i+'.gif?' + d ;
setTimeout('refresh()',60000); // refresh every 60 secs
};

==================

[supposing 60 secs is enough time to download all 20]

If you stick to 'name', try:

document.images['image'+i].src = 'image' + i + '.gif?' + d ;

with an appropriate string and long integer for imagename

Why a LONG integer?
How many images do you want to reload in 60 secs?
JS does not specify such number types.

An image-name or image-id needs to start wth a letter, btw.
and
refreshinterval respectively. But I'm not sure what the exact syntax
thereafter might be, nor how the argument for the onLoad event in the
body tag would be coded for two or more images.

That is why reading the JS-specs, do trial and error with debugging, and
fully discarding the "I guess I don't need to know why", together with or
beter starting with the reading of this NG's FAQ, is so rewarding.
 
E

Evertjan.

Randy Webb wrote on 12 jul 2007 in comp.lang.javascript:
No, they are not "equivalent". The same applies to the document.image
collection as applies to the document.forms collection. The bracket
notation will *always* be preferable and can be used in places where dot
notation will fail:

"My image is named 'my-image', why does document.images.my-image.src
throw an error?"

;-(

Because then the name is not "image1" ?

Seriously [well, sort of]:

Because if JS would try to substact the numeric value
of "image.src" from
the numeric value of "document.images.my",
both of them having no numeric value to speak of,
it would fail,
and even if they would have had numeric values,
the resulting numeric value could not be
on the left side of an assignment statement,
because a numeric value is not a variable or
a value holding part of a DOM-object or other object,
posing as a variable.
 
J

John Dann

Many thanks for the replies.

I need to reveal my ignorance about using JS again - exactly where do
the window.setInterval code lines need to go? I've assumed that they
would go in a <script> block in the HTML body but are otherwise
agnostic as to position. But maybe this is wrong because the images
are not updating but become blanked out after the set interval (in
FF2.0 at least). You can see the page temporarily at:

www.elyweather.co.uk/wdl

(It's the two graphs in the right-hand column that I'm trying to
refresh - there is some other stuff going on in the page, primarily
the regular refreshing of a Flash object but hopefully that's not
interfering. I suspect it's just something in the exact syntax or
positioning of the setInterval code - maybe they need to be in the
same table cell as the image they relate to?)
 
R

Richard Cornford

Randy said:
-Lost said the following on 7/12/2007 12:48 PM:



The URL to a file is the complete string. Whether it has a ? in it or
not, the URL is the entire string. While it may be written in a spec
somewhere that it is not "required" to do so, any browser that would
load a page from cache with a different queryString would be
completely and utterly broken. ...

It is not explicitly written in a specification anywhere. The
specification in question would be RFC 2616 (HTTP 1.1) and the nearest
it gets is in section 13.1.4, where it states:-

| ... . The user agent SHOULD NOT default to either non-transparent
| behaviour, or behaviour that results in abnormally ineffective
caching,
| but MAY be explicitly configured to do so by an explicit action of
| the user.
|
| If the user has overridden the basic caching mechanisms, the user
| agent SHOULD explicitly indicate to the user whenever this results
| in the display of information that might not meet the server's
| transparency requirements (in particular, if the displayed entity is
| known to be stale). ...

- which does give the User Agent the right to do pretty much anything so
long as the user configures it that way (but not by default and not
without indicating what it is doing that deviates from the norm).

This allows for "are not required to", but not in any sense that is
worth worrying about.

Apart from that the (full) URI of a GET request is the thing that
identifiers the resource being requested and so no part of it could be
disregarded when making a decision as to whether a resource could be
retrieved from the cache or not.

Section 3.2 states what a URI is (as far as HTTP is concerned), and
ends:"Uniform Resource Identifiers are simply formatted strings which
identify--via name, location, or any other characteristic--a resource".
Where "any other characteristic" can only refer to the protocol and the
query string (if the latter is are present). (Fragment identifiers do
not identify resources, but instead points within a resource, and so can
be disregarded here.)

Richard.
 
E

Evertjan.

Randy Webb wrote on 12 jul 2007 in comp.lang.javascript:
;-(

Because then the name is not "image1" ?

Seriously [well, sort of]:

Because if JS would try to substact the numeric value
of "image.src" from
the numeric value of "document.images.my",
both of them having no numeric value to speak of,
it would fail,
and even if they would have had numeric values,
the resulting numeric value could not be
on the left side of an assignment statement,
because a numeric value is not a variable or
a value holding part of a DOM-object or other object,
posing as a variable.

Then you agree that the Dot Notation and Bracket Notation are not
"equivalent" but one is better than the other? :)

yes. I only use the bracket one.
 
J

John Dann

Many thanks for all the help - much appreciated. Here's what I've
currently ended up with:

<script type="text/javascript">
function refreshIt(imageName,imgSrc) {
if (!document.images) return;
document.images[imageName].src = imgSrc + '?' + new Date();
}
window.setInterval('refreshIt("'+"image1"+'","'+"image1.gif"+'")',60000);
window.setInterval('refreshIt("'+"image2"+'","'+"image2.gif"+'")',360000);
</script>

This is certainly concise and seems to be working fine, but I've got a
couple of final questions:

First, there are a lot of single and double quotes in the code lines
for window.setinterval. While my present version seems to be OK I can
see that there's a lot of potential for typos in future versions I
might want to create. So I was wondering whether there's any
recommended alternative way of syntax/coding for this particular line
that might be potentially more robust to editing?

I can see that what's happening is building the appropriate string for
the first argument of setInterval but the mixture of single and double
quotes - which I guess is what's catching my eye in particular - is
not easy to read and edit reliably for someone who's first language
isn't JS. Would the use of variables help at all - maybe not? (I know
I asked for concise but clarity/robustness are considerations too.)
But maybe the single/double quotes is something you have to get used
to with JS?

Second question is about the position of the window.setInterval
calls. When I had these calls in a separate code block in the body of
the HTML, the image refresh wasn't working. But moving into the single
code block in the header, as above and as Randy suggested, makes it
all work. Can anyone tell me why please?
 
D

David Mark

Many thanks for all the help - much appreciated. Here's what I've
currently ended up with:

<script type="text/javascript">
function refreshIt(imageName,imgSrc) {
if (!document.images) return;
document.images[imageName].src = imgSrc + '?' + new Date();}

window.setInterval('refreshIt("'+"image1"+'","'+"image1.gif"+'")',60000);
window.setInterval('refreshIt("'+"image2"+'","'+"image2.gif"+'")',360000);
</script>

This is certainly concise and seems to be working fine, but I've got a
couple of final questions:

First, there are a lot of single and double quotes in the code lines
for window.setinterval. While my present version seems to be OK I can
see that there's a lot of potential for typos in future versions I
might want to create. So I was wondering whether there's any
recommended alternative way of syntax/coding for this particular line
that might be potentially more robust to editing?

Yes, you can use a function for the first argument to setInterval,
rather than a string. In this case you would need to use anonymous
functions to pass the parameters to the refreshIt function.
I can see that what's happening is building the appropriate string for
the first argument of setInterval but the mixture of single and double
quotes - which I guess is what's catching my eye in particular - is
not easy to read and edit reliably for someone who's first language
isn't JS. Would the use of variables help at all - maybe not? (I know
I asked for concise but clarity/robustness are considerations too.)
But maybe the single/double quotes is something you have to get used
to with JS?

Second question is about the position of the window.setInterval
calls. When I had these calls in a separate code block in the body of
the HTML, the image refresh wasn't working. But moving into the single
code block in the header, as above and as Randy suggested, makes it
all work. Can anyone tell me why please?

Are you sure that was your problem at the time? It shouldn't make a
bit of difference where you put the setInterval calls. It makes more
sense to put it in the head tag though.
 

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

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top