|
The three topics covered in this week's handout -- preloading images, constrained randomization, and external JavaScript files -- describe options that you may choose to add to your solution for Assignment 2. These features are not required. 1. Pre-loading images The current assignment requires you to work with a large number of images. Image files can take a second or two to stream in and you may find the resultant lags undesirable. To prevent such holdups, you can invoke a function when your page loads (i.e., at the beginning of the main function triggered by the onLoad handler) that pre-loads your image files into Image objects. Here's an example of a simple preloader:
var imageSet = new Array(3);
function loadMaster()
{
var imageNames = new Array("im1.jpg", "im2.jpg", "im3.jpg");
for(i=1; i<4; i++)
{
imageSet[i] = new Image();
imageSet[i].src = imageNames[i];
}
}
The var statement declares a variable called imageSet for use in loadMaster(). Note that this statement is outside the function that uses the variable. This placement allows us to use imageSet in more than one function. Variables used in more than one function are called global. There is a second var statement here, inside the loadMaster() function. That one sets up imageNames, a variable that will only be used within the function. Variables used in only one function are called local. Both var statements create a special kind of variable called an Array -- the capital "A" is required because these arrays (or Arrays) are JavaScript objects. As you know from last week, an array is just a sequential set of items. JavaScript builds a number of arrays automatically (for instance, the navigator.plugins array). You can also create object Arrays of your own. For space and clarity, this example only deals with three images -- really too small a number to require preloading. In the current assignment I've asked you to use 10-15 images; if you want to add preloading as an option, you'll need to increase the components of imageNames accordingly. Here's how loadMaster() works: First we create an array to contain a series of file names. Then we come to a for loop that runs once for each image in our image set. Note that this loop runs from 1 to 3 (i<4) instead of the usual 0 to 2 (i<3). We've done this in anticipation of using these preloaded images with the random-number function you learned last week. Remember that this function returns integers between 1 and some maximum -- so in this case we need to exclude zero and begin counting from 1. Within this loop we do two things on each iteration. First we create an Image object. Like other JavaScript objects, this is a structure for certain information, in this case information about an image file. Next we set the src (source) property of the Image object to a value stored in the imageNames array that we defined outside the loop. These two operations pre-load the image file. They cause the browser to load each image file invisibly into offline memory (the browser cache). Images in the cache don't need to be retrieved subsequently from the server. Once you've pre-loaded images into an array of Image objects, you need to change the instructions that choose images at random. Without preloading you would write something like this:
document.kenny.src = ("im" + randy + ".jpg");
With preloading, you instead write: document.kenny.src = imageSet[randy].src; That's all there is to pre-loading. 2. Generating random numbers with constraints Last week you learned one way to generate a number at random: Math.ceil(Math.random()*x) This statement works fine if all you want to do is pick any number between 1 and x, inclusive. However, if you're trying to come up with consistently surprising (!?) content, you'll need something a little more sophisticated. Run the standard randomizer seven times with a range of 1-10 and you could easily come up with: 5,7,3,3,3,4,10. Nothing prevents that annoying run of threes. More typically we'll want to exclude from our random selection any number that came up on a previous run of the function. That way the randomizer might hit the same value repeatedly (for instance, 5,7,5,3,5,10,5) but never twice in succession. The simplest way to make this adjustment involves placing your randomizer within a while loop:
var randyOld = 0;
var randy = 0;
while(randy == randyOld)
{
randy = Math.round(Math.random()*10);
}
randyOld = randy;
The while statement tells the browser to execute whatever is within the curly braces {} so long as the test condition is true. In this case it tells the browser to come up with a new random number if the present number (randy) matches the previous number (randyOld). Once a difference occurs, the browser goes on to the first statement outside the braces, which assigns the current value of randy to the storage variable randyOld so that the test can be run the next time a random number is needed. There's one immediate catch to this scheme: since the while statement must have two values to compare, and since it will only generate a random number if those two values are identical, you have to give randy and randyOld the same initial value. You can do this by using the var statement to initialize your two variables at the beginning of your <SCRIPT> container. Those two var statements in the example above would be placed at the very top of the <SCRIPT> container, outside any functions. If you're interested in further constraining your random numbers, consider adding more record variables. Just remember to update them outside your while loop. 3. External JavaScript files All the scripts we've built so far have been designed for use within a single page. You can also write generic scripts for use with multiple pages. These scripts are invoked through a slightly modified <SCRIPT> container like this: <script language="JavaScript" src="footLocker.js"></script> Note that the closing </SCRIPT> tag is required even though the container is empty -- and there's no point filling it up because any JavaScript statements within this container will be ignored. An external JavaScript file is a plain text (ASCII) file containing JavaScript statements, either direct-execution statements or functions -- but though the external JavaScript material is invoked by a <SCRIPT> container on a Web page, the external file itself has no <SCRIPT> container. If we wanted the example above to invoke some statements that put a footer at the bottom of a Web page, contents of the external file footLocker.js might look like this:
document.write("<p align='center'>");
document.write("Page Last Modified: " + document.lastModified);
We mentioned the lastModified property of the document object last week. It gives a time and date for the last changes to any given page (though remember that this information is only meaningful when your page is loaded from a server). The statements above are directly executed, which is just fine if they're the only JavaScript instructions in the file footLocker.js. If you want to execute several sets of statements at different times, you'll have to set them up within the external file as functions; and if you want these functions triggered in different places, you'll need at least three sets of <SCRIPT> containers in your HTML page. For example: <html> <head> <script language="JavaScript" src="utilities.js"></script> </head> <body> <script language="JavaScript">headsUp();</script> Here's the bulk of my Web page... <script language="JavaScript">footsie();</script> </body> </html> Both functions, headsUp() and footsie(), are defined within the external file utilities.js, which is invoked in the first <SCRIPT> container, the one in the <HEAD> section of the Web page. The functions are invoked as they are needed on the page, in separate <SCRIPT> containers within the <BODY> section. Why would you want to use external JavaScript pages? Our examples here suggest one application: creating standard header and footer information that can be appended to every page of a complex site. You might also want to write JavaScript functions that invoke other functions maintained remotely, much as software libraries are used in programming. Finally, consider what would happen if you needed to change the footers on each one of 200 pages. If you brought in your footers via an external page, you'd only have to make that change once. A final note: Most Web servers need to be configured to use external JavaScript files. It's a fairly small matter but it does require the attention of the server administrator. Raven is configured for external JavaScript. Just remember to upload external JavaScript files as text. |