[Techtalk] script

Almut Behrens almut-behrens at gmx.net
Sat Apr 12 00:38:15 EST 2003


On Fri, Apr 11, 2003 at 02:55:39PM -0400, MelissaL.Wise at mail.state.ky.us wrote:
> I was putting the pictures 2 subdirectories into my HTML folder.  If I put
> the pictures at the root of the HTML folder where my INDEX.HTML is (which is
> the page I want to cycle pictures), it works fine. I changed the img src
> paths to reflect the subdirectory in which I had them located it, but it
> would only load the first pic, then error out.  


have you also modified the line

  imgs[i].src = "frame"+i+".jpg";

to reflect the changed image-URLs?  The URL you specify as the
src of the image in the HTML part (<img src="...">) is the image
that gets loaded initially. Subsequent image names will be taken
from the imgs[]-array (i.e. imgs[i].src), and all of them have to be
found. Once there's an invalid URL, the image doesn't load, and, as a
consequence, the "onload" handler will not be called -- so the cycling
stops at that point...

In our case this means that you need

  imgs[i].src = "images/frame"+i+".jpg";

if you have

  <img src="images/frame1.jpg" ... >


Of course, this is suboptimal, as you always have to edit things in
several places, when you change something...
Thus, we'll develop a less error-prone version below, step by step:

Ideally, we'd like to specify the list of images in just one place,
so we start out with the following code:


<html>
<head>
<script language="JavaScript">

img_url = ["frame1.jpg", "frame2.jpg", "frame3.jpg", "frame4.jpg"];

delay = 1000;  // in msec
n = img_url.length;

imgs = new Array();

for (i=0; i<n; i++) {
  // preload images, so they are in the cache
  imgs[i] = new Image();
  imgs[i].src = img_url[i];
}

c = 0;

function nextimg() {
  document.myimg.src = imgs[c].src;
  c++;
  if (c>=n) c=0;
}

</script>
</head>

<body>
<img src="frame1.jpg" name="myimg" onload="setTimeout('nextimg()', delay)">
</body>
</html>


As you can see, we defined an array "img_url" that contains the URLs
of all the images we want to display. (There are also several minor
changes elsewhere, as the first element of the array is img_url[0],
so we now use indices [0]..[3] instead of [1]..[4], as before.)
Though this piece of code works, it's not yet quite what we want, as we
still have the duplicated URL src="frame1.jpg" in the HTML part at the
bottom.

Unfortunately, we cannot simply write src=img_url[0], as this is in
the HTML part of the document, so the javascript variable will not be
expanded...
A second try might be something like src="javascript:img_url[0]", but
this doesn't work either.  So, we have to use a considerably more
cumbersome construction, which generates the necessary piece of HTML
code on the fly (with the value of the first array element img_url[0]
expanded), and inserts this code fragment at the appropriate place.
Note, that this is just in order to avoid having to maintain two
seperate instances of the same string "frame1.jpg".
With this modification we have:

<html>
<head>
<script language="JavaScript">

img_url = ["frame1.jpg", "frame2.jpg", "frame3.jpg", "frame4.jpg"];

delay = 1000;  // in msec
n = img_url.length;

imgs = new Array();

for (i=0; i<n; i++) {
  // preload images, so they are in the cache
  imgs[i] = new Image();
  imgs[i].src = img_url[i];
}

c = 0;

function nextimg() {
  document.myimg.src = imgs[c].src;
  c++;
  if (c>=n) c=0;
}

</script>
</head>

<body>
<script language="JavaScript">
  document.write('<img src="' + img_url[0] + '" name="myimg" onload="setTimeout(\'nextimg()\', delay)">');
</script>
</body>
</html>

The piece of javascript between the second <script>...</script> tags
executes within the HTML body of the document, and the function
document.write() inserts its string in that very place of the document.
Now, this is where things really start to get ugly (wrt legibility), so
watch out to get the quoting right... 

However, we've achieved what we wanted: we now have a single place to
put all image URLs. This could be anything like

img_url = [
  "images/frame1.jpg",
  "images/frame2.jpg",
  "newimages/i3.jpg",
  "newimages/IMG4.jpg",
  "http://www99.adserver.com/xyz/whatever.jpg",
];

(but they should still all fit in the display area occupied by the
first image shown...)


To simplify things somewhat, we could get rid of the image preloading
stuff. This is really only a performance issue, the idea being, that
all images are loaded immediately when the document is opened.
Otherwise, each image would be loaded at the very moment it is to be
displayed. Depending on the speed of the network connection, this
could disturb the intended timing, so the slide show might not look as
smooth as desired. (With images on a local machine, there would hardly
be a difference, though.)

The actual loading/displaying of an image is triggered simply by
assigning an URL to the "src"-attribute of an Image object, e.g.

  document.myimg.src = "frame1.jpg";
  document.myimg.src = imgs[c].src;
  document.myimg.src = img_url[c];

(In our case we created the Image object implicitly via the HTML
<img> tag -- the respective javascript code would be
"img = new Image(); img.src = 'URL';" )


Thus, the simplified document would finally look something like:

<html>
<head>
<script language="JavaScript">

img_url = [
  "images/frame1.jpg",
  "images/frame2.jpg",
  "images/frame3.jpg",
  "images/frame4.jpg"
];

delay = 1000;  // in msec
n = img_url.length;
c = 0;

function nextimg() {
  document.myimg.src = img_url[c];
  c++;
  if (c>=n) c=0;
}

</script>
</head>

<body>
<script language="JavaScript">
  document.write(
    '<img src="' + img_url[0] +
    '" name="myimg" onload="setTimeout(\'nextimg()\', delay)">'
  );
</script>
</body>
</html>


Hope this clarifies things somewhat...

Almut



More information about the Techtalk mailing list