Notes 14
— print (last updated: Jul 15, 2009) print

Select font size:

JavaScript Access to style properties

Once we have obtained a JavaScript object for an HTML element, say with id="elt", we can access its style subobject (property) as follows:
var elt = document.getElementById("elt"); 

var style = elt.style;
With this style variable, all the style properties of that particular element can be read and or modified. For example, to set that element's foreground color to red and background color to yellow, we would use the code
style.color = "red";
style.backgroundColor = "yellow";
What we need to understand is how the CSS property with the name background-color is transformed into the JavaScript variable backgroundColor. The transformation is simple: change the letter following a dash (-) to upper case and then remove the dashes.

Often it is just as simple to chain the objects together with the "." operation; for example, the above two operations can be written:
elt.style.color = "red";
elt.style.backgroundColor = "yellow";

Hyperlink-activated style change

The first version of this program shows illustrates the usage of two differerent functions, one to set the colors and another to reset them to the original:
<html>
<head>
<title>Set Colors</title>

<style type="text/css">
p.special {
  width:200px;
  padding:10px;
  border:solid thin black;
  color:white;
  background-color:blue;
}
</style>

<script type="text/javascript">
<!--
function set_colors() 
{ 
   var tester = document.getElementById("tester");
   tester.style.color = 'red';
   tester.style.backgroundColor = 'yellow';
}
function reset_colors() 
{ 
   var tester = document.getElementById("tester");
   tester.style.color = 'white';
   tester.style.backgroundColor = 'blue';
}
// -->
</script>

</head>

<body>
  
<a href="javascript:set_colors()">Set</a>
<br />
<a href="javascript:reset_colors()">Reset</a>

<p id="tester" class="special">TESTING</p>
 
</body>
</html>

The effects of this program can be seen through this link.

Simplification using function parameters

The only differences between the two functions set_colors and reset_colors are the choice of colors. We can simplify the programming here by using one function only, set_colors, but allowing it to have paramters as follows:
<html>
<head>
<title>Set Colors, parameterized</title>

<style type="text/css">
p.special {
  width:200px;
  padding:10px;
  border:solid thin black;
  color:white;
  background-color:blue;
}
</style>

<script type="text/javascript">
<!--
function set_colors(fg,bg) 
{ 
   var tester = document.getElementById("tester");
   tester.style.color = fg;
   tester.style.backgroundColor = bg;
}
// -->
</script>

</head>

<body>
  
<a href="javascript:set_colors('red','yellow')">Set</a>
<br />
<a href="javascript:set_colors('white','blue')">Reset</a>

<p id="tester" class="special">TESTING</p>
 
</body>
</html>

This program functions exactly like the previous one. The only difference is that it is programmatically "simpler". For example, when the first link is activated, the JavaScript function call is
set_colors('red','yellow')
The values 'red' and 'yellow' are called actual parameters. They correspond to the so-called formal parameters fg and bg in the function definition. This has the effect of setting:
fg = 'red'; 
bg = 'yellow';
prior to executing the body of the function. Therefore we get the desired effect when executing the body:
tester.style.color = 'red';
tester.style.backgroundColor = 'yellow';

JavaScript arrays

Arrays in JavaScript provide a means of accessing a JavaScript entity via an index. The syntax to create an array is this:
var a = new Array()
After a has been created, we can assign
a[index] = entity
where index is any integer, and entity is any JavaScript entity (actually index can be more general than just an integer, but this is beyond the scope of these notes). At a later point, we can use the information stored by the expression:
a[index]
For example:
var names = new Array()
names[1] = "jim"
names[2] = "april"
names[3] = "bill"
names[4] = "jane"
At a later point in the code, we can access these entities via a integer variable, e.g.
var ind = // some integer between 1 and 4
document.writeln( "the selected name is " + names[ind] )

Color Sequencing

The idea of "sequencing" means to make a single action have different related effects which appear in some sequence. The simple idea is like a slide show in which the click of a button advances from one image to the next. The button click is the single action but it has different effects. What we need to keep track of is the notion of the "state" of the system at a certain point so that we know how to go to the next state.

Our goal is to create the following example:
Color Sequencing
Here is the starter code:
<html>
<head>
<title>Color Sequence</title>

<style type="text/css">
div {
  width:100;
  height:100;
  border:solid thin black;
  background-color:red;
}
</style>

</head>
<body>

<div id="block"></div>

<p>
Color: <span id="name">red</span>
</p>

<a href="">Change Color</a>

</body>
</html>

Pressing the hyperlink will activate the JavaScript function change_color which should move the colors like this:
red green blue, and then back to red.
In order to achieve this effect, we keep track of an integer variable ind which can be thought of as the state of the sequencing operation:
ind = 1  =>  color = red
ind = 2  =>  color = green
ind = 3  =>  color = blue
The ind variable is maintained outside of any function and the change_color function changes this state information and sets color accordingly. We want to "cycle" 1 2 3, and then back to 1. The JavaScript code which achieves this effect is:
var ind = 1

function change_color() {
  ind = ind + 1             // go up by 1
  if (ind > 3) ind = 1      // if beyond 3, go back to 1
  
  ...
An array colors (plural) is used to associate the index to the desired color:
var colors = new Array()
colors[1] = "red"
colors[2] = "green"
colors[3] = "blue"
Inside the change_color function, we can identify the variable color (singular) by
  var color = colors[ind]    // note the singular/plural difference
Then, apply this color appropriately in our code:
  block.style.backgroundColor = color   // set the background-color
  name.innerHTML = color                // set the span's content
Here is the full code:
<html>
<head>
<title>Color Sequencing</title>

<style type="text/css">
div {
  width:100;
  height:100;
  border:solid thin black;
  background-color: red;
}
</style>

<script type="text/javascript">

var colors = new Array()
colors[1] = "red"
colors[2] = "green"
colors[3] = "blue"

var ind = 1

function change_color()
{
  ind = ind + 1
  if (ind > 3) ind = 1

  var color = colors[ind]

  var block = document.getElementById("block")
  var name = document.getElementById("name")

  block.style.backgroundColor = color
  name.innerHTML = color
}
</script>

</head>
<body>

<div id="block"></div>

<p>
Color: <span id="name">red</span>
</p>

<a href="javascript:change_color()">Change Color</a>

</body>
</html>

Image Objects in JavaScript, preloading

JavaScript has a special object called Image which can be used to "hold" an image. It is declared like this:
var im = new Image()
The keyword new is a special operator needed to create objects. Setting the src property of this image object
im.src = "some-image-url"
effectively loads the image into the browser through JavaScript code. This is, in fact, the correct way to preload an images for a document, so that when it is needed in a dynamic HTML context, it is already available in the browser.

Image Sequencing

Sequencing through a set of images turns out to be very much like sequencing through colors. The main difference is that the initialization of an image sequence requires two steps, e.g.,
var images = new Array()
images[1] = new Image()
images[1].src = "first-image"
images[2] = new Image()
images[2].src = "second-image"
// ...
These steps are executed outside any function, thereby having the effect of preloading these images. At some later point, once we have a representation of a target image in JavaScript:
var my_img = document.getElementById( "my_img" )
then we can set this image to any of the indexed images via the statement:
my_img.src = images[ind].src       // ind is some integer index

Image sequencing via a hyperlink

This example consists of four images below that I want to sequence through (taken on my travels to Mexico). Click each to isolate and download into a folder, mexico:
town.jpg lake.jpg statue.jpg cathedral.jpg
The goal is to create this JavaScript document:
Image Sequencing
As mentioned above, the key initial steps are:
  1. create an Array to hold the images
  2. create an image object for each of the 4 images
  3. preload the image by setting src to the desired image file name
We user the following steps:
var images = new Array()  // use an Array so we can use indices effectively
images[1] = new Image()
images[1].src = "mexico/town.jpg"
images[2] = new Image()
images[2].src = "mexico/lake.jpg"
images[3] = new Image()
images[3].src = "mexico/statue.jpg"
images[4] = new Image()
images[4].src = "mexico/cathedral.jpg"
Then, given the image within the document:
<img id="main" src="mexico/town.jpg" />
we can set this image from to an alternative choice by the statements:
var main = document.getElementById("main")
main.src = images[ind].src
Here it the full program:
<html>
<head>
<title>Image Sequence</title>

<script type="text/javascript">

// preload images
var images = new Array()  // use an Array so we can use indices effectively
images[1] = new Image()
images[1].src = "mexico/town.jpg"
images[2] = new Image()
images[2].src = "mexico/lake.jpg"
images[3] = new Image()
images[3].src = "mexico/statue.jpg"
images[4] = new Image()
images[4].src = "mexico/cathedral.jpg"

// sequence between images using the index "ind"
var ind = 1;
function changeImage() {
  ind = ind + 1
  if (ind > 4) ind = 1

  var image = images[ind]

  var main = document.getElementById("main")
  var num = document.getElementById("num")

  main.src = image.src
  num.innerHTML = ind
}
</script>
</head>

<body> 

<img id="main" src="mexico/town.jpg" />

<div>Slide <span id="num">1</span></div>

<p><a href="javascript:changeImage()">Next</a></p>

</body>
</html>

Timed image sequencing

A very slight variation of the above program allows a timed image sequencing, whereby the images change after a preset timer interval. The effects of this program can be seen here:
Timed Image Sequencing
The key idea is to replace the hyperlink activation of the call to changeImage() by a timer-generated call with this statement:
setInterval( "changeImage()", 2000 )
The timing is started in the function init() which is activated when the document is loaded. There are two ways to do so. The way we have done it in the revised document uses the JavaScript statement:
window.onload = init
An alternative way to set the onload property is by adding the onload attribute in the body:
<body onload="init()">
The setInterval call used in this way will invoke changeImage() every 2000 milliseconds, i.e., every 2 seconds.

Here is the program:
<html>
<head>
<title>Timed Image Sequence</title>

<script type="text/javascript">

// preload images
var images = new Array()  // use an Array so we can use indices effectively
images[1] = new Image()
images[1].src = "mexico/town.jpg"
images[2] = new Image()
images[2].src = "mexico/lake.jpg"
images[3] = new Image()
images[3].src = "mexico/statue.jpg"
images[4] = new Image()
images[4].src = "mexico/cathedral.jpg"

// sequence between images using index, ind
var ind = 1;
function changeImage() {
  ind = ind + 1
  if (ind > 4) ind = 1

  var image = images[ind]

  var main = document.getElementById("main")
  var num = document.getElementById("num")

  main.src = image.src
  num.innerHTML = ind
}

function init() {
  setInterval( "changeImage()", 2000 )  // call changeImage() every 2 seconds
}

window.onload = init

</script>
</head>
<body>
<img id="main" src="mexico/town.jpg" />
<div>Slide <span id="num">1</span></div>
</body>
</html>


© Robert M. Kline