Interacting with the DOM

This is based on pp 230 in the book.

Getting an Element

 

This is a simple set of files to show accessing DOM elements, first the HTML

The only things really of interest here are the heading element on line 8 which has the id attribute of “Head” and the script on line 9. Everything of interest happens in the script. What happens when the browser reads this HTML file to display it first creates an internal data structure it can work with more easily than the text. The book describes this in much more detail on pp 238.

On line 3, the getElementByID statement creates a reference to the part of the DOM that deals with the Head tag on line 8 in the html file. Because the part of the browser that displays (paints) the screen with what you see is different from the part that runs the JavaScript, it’s necessary for the two pieces to have a connection so they can interact with each other. That’s what the code on line 3 is doing, it’s given the JavaScript a reference into the DOM that it can use to change what’s displayed. The id on the tag on line 8 in the html file lets the JavaScript specify exactly what piece of the DOM to get the reference to.

 

This DOM reference is a complex piece of data, it’s referred to as an Object in JavaScript (and most other languages as well). If we put a debugger statement after line 3, we can get an idea of what’s in the DOM element reference.

 

Here’s what hovering over the HeadE variable looks like after execution stops at the debugger line. All these items in the displayed list are properties (data items) belonging to the Head DOM element that is referenced by the HeadE variable.

As you can see, there’s a lot of stuff available from that HeadE reference! DOM elements are quite complex objects, which means that there’s a lot of things you can do to it with JavaScript.

Using all this for Ice Cream

Using our earlier Ice Cream example with some added elements. Notice that the id attributes, they’re used to get to each element from inside JavaScript, they identify individual elements.

 

This is going to be used for a simple (too simple!) interactive system modeling ice cream eating.

The new elements on line 9 and 10 will be used in the JavaScript code so they need to be identified so JavaScript can access them. That’s where the id’s come in. Without them it would be very difficult to specify which HTML elements the JavaScript was trying to change.

 

Here’s the JavaScript in IceCreamDOM.js

 

 

On line 3 and 4 the code gets the references to the Msg and List elements by specifying them by their id. The text inside a paragraph, header, etc. is part of the property of DOM elements named the innerHTML and can be read and changed by the JavaScript.

To start, at line 9 we change the message to show how many scoops are left by setting the innerHTML of the msgE variable. The msgE variable contains a reference to the Msg paragraph because we loaded it at line 3, so anything that paragraph can do, we can do it through the msgE variable. In this case we’re setting the text for it.

Lines 11 – 15 set up the list paragraph to have an entry for each remaining scoop which is updated on each iteration of the while loop (line 8 – 20). Rather than interact with the List paragraph repeatedly, this code uses the innerTxt variable to build up the output text. On line 11, the innerTxt variable is loaded with an empty string to be sure there’s nothing left in it from the previous iteration of the while loop. Then lines 12 – 14 fill the innerTxt variable with a name for each remaining scoop using a for loop which counts up from 1 to the value in scoops. Notice that the end test is idx <= scoops. If it were idx < scoops, it wouldn’t do the final value, it would stop on the next to last scoop. Finally, on line 15, the string just built up is put into the List paragraph.

Line 17 puts up an alert box to let the user interact with the program. In reality, this is mainly there to slow down execution of the program. If it weren’t there and the loop just ran without any kind of interaction it would run so fast that the user couldn’t see it change, it would appear to be done immediately.

After the scoops variable has been decremented to zero on line 19, the while loop ends and the final state is shown by lines 21 and 22.

Here’s what this looks like the first time through the while loop:

Each time through the loop, this alert box will pop up and after the user clicks on OK one scoop will be removed and it will show the dialog again.

This works, but is really obnoxious! To make it a bit less so, we can use a callback.

Callbacks

This is discussed on page 249 in the book where they talk about the onload event. Here I’m talking about a different event, but all events between the browser and JavaScript are handled the same way, with a callback. As the book explains, callbacks are functions (blocks of code) that are run when an event occurs. In this case the idea is that we’re going to set up a piece of JavaScript code which will be run when the user clicks on the Msg paragraph. To do that, we just set the onclick event value in the Msg paragraph to the function you want to have run when the element is clicked.

Functions are discussed in the book on page 83, but for what we’re doing, the callback we need is pretty simple.

I put this into a separate JavaScript file so I had to change the HTML file to reference it.

The only change is the src attribute on line 11, but if you don’t reference the JavaScript file you want, you won’t get it!

This is the Ice Cream JavaScript code rearranged to use a callback that is run whenever the user clicks on the Msg paragraph.

There are two functions here, repaint on lines 11 to 29 and catchClick on lines 31 to 34. The catchClick function is the callback and is put into the onclick property of the Msg paragraph on line 8. The repaint function actually does the changes to the innerHTML of the Msg and List paragraphs so the user can see what’s going on. Having all the repainting code in a function rather than repeated multiple times in the code is good coding practice because it keeps it all in one place. Not only is it easier to write once, but if you decide to change how the display is done, you just have to get it right once!

On line 8 a reference to the repaint function is put into the onclick property so onClick is called whenever the Msg paragraph is clicked on.

Line 9 does the first paint of the screen to show the initial state of everything.

When the Msg paragraph is clicked, catchClick is called, on Line 32 it first decrements the scoops variable, then calls the repaint function to show the user the new state.

Notice the if else in repaint. Line 12 is for normal cases where there are scoops left, line 21 is for the case where there are no more, and line 25 is for everything else, i.e. where the scoops variable has gone negative.

Seeing it in action

Putting a debugger statement at line 32 allows single stepping through all this. Here’s what it looks like on the first click.

You can now step through the code to watch how it executes, however, to follow the execution into the repaint function, when you get to that line, use the Step Into icon rather than the usual Step Over.

If you do that on line 34, you’ll wind up inside the repaint function and you can step through that to see how it works. If you’re in a function and have seen enough but want to get back to the place where the function was called, you can use the Step Out debugger icon. It lets the function complete normally and stops execution at the next statement after the function call.