Answers to Exercises, Chapter 14


Test Questions

Most of the test questions ask you to write JavaScript, and the answers below are in JavaScript, but you can use ActionScript instead if you prefer. The only difference will be in the need to declare the types of your variables.

  1. There are several possible answers, but if we simply observe that the value of commission never changes, so we can substitute its value wherever it appears, then the second version of the script becomes (in JavaScript).

    var payment = amount * 0.1
    if (payment < 10) payment = 0

    In ActionScript, we must declare the type of payment

    var payment:Number = amount * 0.1
    if (payment < 10) payment = 0
  2. It is not possible to know how many times a loop will be executed if the number depends on some value that is obtained from a source external to the program. A common external source for data is input typed or entered by a user using some other control. Another possibility is data received over a network connection, or read from a file. The format of data may also make it infeasible to know how many times a loop is to be executed. To take a particular example, if you write a script to add up all the numbers in a data file, you would probably use a loop, similar to the one in our answer to question 3 below, but you would have no way of knowing how many times that loop would be executed until you had read all the values in the file. Even if the number of values was included as the first thing in the file, it could be different for each file you needed to process.
  3. In ECMAScript, the first element of an array a is a[0], so a[1] is the second element, and so on. In general, a[n] is the (n+1)th entry. Putting that another way, the nth entry is a[n-1] The property a.length holds the total number of elements in a, so the last element (the "length-th", as it were) is a[a.length-1]

    There are many different ways of adding together all the elements of an array a, but the following is probably the simplest (in JavaScript):

    var sum = 0
    for (var i = 0; i < a.length; i = i + 1)
      sum = sum + a[i]

    This leaves the total in sum. Note that we haven't checked that a actually is an array, which we would have to in production code if it was passed as an argument to a function, since JavaScript would not check the type for us. The loop gives the right answer if a is an empty array (one that has no elements in it), though.

  4. If there were no images on the page, the method call document.getElementsByTagName("img") would return an empty array, with no elements, so all_images.length would be equal to 0 and the test in the head of the loop would fail the first time it was evaluated, which is on entry to the loop. Therefore the loop body would never be executed and the value of max_width would remain 0.

    For calculating the width of the narrowest image, the structure of the code could remain the same, with min_width replacing max_width (not that the name makes any difference to the execution, but it makes the code easier to read) and the test in the conditional inside the loop being changed from > to <. The problem with computing the minimum width lies in deciding what value to set min_width to at the beginning. There are two choices:

    min_width could be set to the biggest possible number, so that by the same logic as our original program, it would be replaced as soon as an image with a real width was processed. ECMAScript's built-in Number object has a property MAX_VALUE, which is the biggest number that scripts can manipulate. However, you could use any very large number that you were certain was bigger than any image on a Web page could ever be. This gives the following code fragment:

    var min_width = Number.MAX_VALUE
    var all_images = document.getElementsByTagName("img")
    for (var i = 0; i < all_images.length; i = i+1)
      if (all_images[i].width < min_width)
        min_width = all_images[i].width

    The alternative approach would be to set min_width to a negative number to begin with. Within the loop, if min_width is negative, you assign the current image's width to it. This will only happen the first time an image is processed, but you will have to go on doing the test, so this version is less efficient.

    var min_width = -1
    var all_images = document.getElementsByTagName("img")
      if (min_width < 0 || all_images[i].width < min_width)
        min_width = all_images[i].width

    Notice that these two versions leave different values in min_width if there are no images on the page.

  5. The following two functions would be acceptable as answers here, given the level at which we have described JavaScript. For serious work, some checking on the type and range of the arguments should be included. You will notice that we've re-used the code from our answer to Question 3 in the second function. There would be a good case for making the summation into its own function, so it could be re-used. We leave that refinement as a further exercise.

    function average2(a, b) {
      return (a+b)/2
    function average(a) {
      var sum = 0
        sum = sum + a[i]
      return sum/a.length
  6. This task can be performed using code that is very similar to the fragment on page 557, wrapped up as a function, like this:

    function append_paragraph(s) {
      var h1 = document.createElement("p")
      var body = document.getElementsByTagName("body")[0]

Discussion Topics: Hints and Tips

  1. There are good arguments to be made on both sides of this question. Enforced type declarations permit more sorts of error to be caught at compile-time. Their absence allows values of different types to be stored in the location associated with a variable, which enables a more flexible and dynamic style of programming. Opinion ebbs and flows as to which of these arguments is the stronger – at the moment, dynamic languages are in the ascendant, but this will surely pass. Think about the way you write programs and the sorts of mistake you make to see which side you are on. You may have other considerations to put forward as well.
  2. Although this question is phrased hypothetically, Web and multimedia authoring programs, such as Dreamweaver and Flash, already provide such facilities, so you could start by surveying these and see whether you can think of anything better. For the second part of the question, consider who is better placed to create interactivity – designers or programmers?
  3. If you are short of ideas for this topic, look at the recommendations being developed by the W3C Web Applications Working Group.

Practical Tasks: Hints and Tips

The value of these exercises lies in doing them. Some of them, notably the first, can be done using pre-built behaviours in Dreamweaver; others could probably be done best using one of the JavaScript libraries that we mention briefly on page 566. However, we expect you to create your own solution from scratch – the exercises are to help you learn, not necessarily to get the task achieved in the best way.

We assume that instructors will have provided some form of programming help for individuals, which will be much more effective than any general advice we can offer.

Always keep in mind that the most important property of a program is that it should be correct, that is, it should do what it is supposed to. Next, it should be maintainable, which means that it needs to be readable and easy to follow. Efficiency comes third, although it should not be neglected entirely.

Expect to make mistakes. Current versions of all the major browsers have some tools to assist with debugging JavaScript built in to them. Notably, they all have an "error console" where you will find messages diagnosing any syntax errors in your script, or telling you about errors that occur while it is running. Similar messages are written to the Compiler Errors panel in Flash. You can use the alert function in JavaScript or the trace function in ActionScript to write messages as your program runs. Both functions take a string as their argument, alert writes it in an alert box, trace sends it to Flash's Output panel. In either case, the string can be created by concatenating literal strings with variables, so you can use these functions to tell you the values of your variables at important points in your script.

More assistance is available in the form of interactive debuggers, but try to work out what is going wrong by thinking about the program and reading the code before you get mesmerized watching the values of all the variables as execution proceeds.

For the JavaScript examples, please see the note under Examples>14 about Internet Explorer. Since these are educational examples, not real tasks, we strongly recommend that you avoid Explorer's non-standard behaviour and only test your answers on a browser that implements the standards correctly, such as the latest versions of Firefox, Opera and Safari. (But see the note about implementations of addEventListener on the errata page.)

  1. As we mention on p. 557, you can assign a new value to the src attribute of an img element to change the image displayed. It is easiest to require the img to have an id attribute, so you can access it easily in your script. You will need to attach listeners for the mouseover and mouseout events to the img.
  2. When considering additional checks, don't be too ambitious. Checking that an email address is well-formed according to the relevant standard is quite difficult, and not always a good idea, because some real addresses are not, strictly speaking, legal. Confine yourself to looking for something that could be a domain name in the right place.
  3. This exercise does not need any further hint.
  4. You need to define a function that you can call directly, or from inside the listener.
  5. The total number of frames in a MovieClip object is available in its totalFrames property. A Slider component has minimum and maximum properties, which hold the corresponding values.
  6. Note that you need to change both the FLA document and the script in the .as file.
  7. There are several ways of making a movie appear and disappear. Experts would probably add it to and remove it from the display list, but an easier option for the beginner may be to set the alpha property to 0 when you want the movie to be invisible and 1 when you want to be able to see it (and not see what is behind it). You don't have to keep the movies in sync all the time, just make sure that when you switch from one to the other they are at the same frame. (You might prefer to make two new movies yourself, differing only in colour, so you can see whether they are correctly synchronized.)