Session 16: Using JavaScript to Change the Content of a Page
Download this starter code to use throughout the session.
Reviewing Our First Tour of JavaScript
Last time, we began to learn JavaScript. We ended up writing code such as this using these features of the language:
-
expressions
-
primitive
- literals: numbers, strings, and booleans
- named values: variables and constants
- compound: using operators to combine expressions
-
primitive
- statements: assigning a value to a name
The different kinds of value that an expressions can be, whether
primitive or compound, are called data types.
We used two data types in our code to compute a circle's area,
numbers and strings. Last time, we also saw the boolean data
type and the special value undefined
. We will
learn about a couple of more data types in the coming weeks,
including one general category today.
Our code to compute the area of a circle works. We can make it even better by learning about JavaScript objects, which are packages that contain data and code we can use.
Once we know how to work with JavaScript objects, we can learn how to use JavaScript to interact with the HTML on a web page. That is our end goal for the day: to write a script in JavaScript that modifies the content of a web page.
JavaScript Objects and Data Properties
... or: Why Am I Defining Pi?
The first shortcoming of our circle area code is one of correctness: pi is not exactly 3.14159. We can't write the exact value of pi, of course, but we can do better with more digits of precision. Furthermore, we would like for programs to be consistent, using the same value for pi in every program.
JavaScript defines a common, more precise value of pi in the
primitive Math.PI
:
❯ Math.PI ← 3.141592653589793
The name used in this expression leads us to an important new
JavaScript data type: Math
is an
object. An object is a package containing
multiple parts.
Consider a typical US postal address. It consists of a street address, a city, a state, and a zip code. It might also include an apartment number or a second line associated with the street. A postal address is a thing itself, but we can also think of it in terms of its parts.
Or think of a pizza. A pizza has many parts: crust, sauce, cheese, and toppings. The toppings might include sausage, peppers, and mushrooms. Some of the parts are made up of parts themselves, such as the crust and the sauce.
Math
is an object that contains a value named
PI
. Notice the uppercase letters... Recall from
last time that JavaScript is case-sensitive.
We say that PI
is a
data property
of the Math
object. Math
contains
several other data properties, as you can see in
the online documentation.
We use a period, .
, to access a property of an
object: object.property
.
It turns out that JavaScript strings are objects, too. Among
other things, they contain the handy data property
length
:
❯ let name = 'Eugene'; ← undefined ❯ name.length ← 6
We will see several other useful objects in the next few weeks. Most importantly, a web browser will give us a webpage in the form of a JavaScript object!
JavaScript Objects and Methods
A second shortcoming of our program is one of functionality: We would like to display the area on a web page somewhere, but the program produces a string value, like any expression.
Objects have a second kind of property: methods. A method is a piece of code that can do something for us.
The Math
object
provides many methods, including sqrt()
and
floor()
. It also includes pow()
,
which is short for 'power'. We can use pow()
in
our code:
> let radius = 4.2; ← undefined > Math.PI * Math.pow(radius,2); ← 55.41769440932395
The String
object
also provides many methods. String methods are important to us
because there are so few operators for working with strings.
Among the string methods are toLowerCase()
,
substr()
(short for 'substring'), and
trim()
.
❯ let name = 'Eugene'; ← undefined ❯ name.toLowerCase() ← "eugene" ❯ name ← "Eugene" ❯ let text = ' I am here. '; ← undefined ❯ text.trim() ← "I am here."
All of these methods work like operators: they create a compound expression that has a value.
Other methods work like a statement: they take an action.
For example: The console we have been working with is itself an
object, with a log()
method.
❯ console.log('Hello, world'); [Log] Hello, world ← undefined ❯ console.log(Math.PI * 2 * 2); [Log] 12.566370614359172 ← undefined
The first line of output is the result of an action: writing to the screen. The second line of output is the value of the expression.
The Resulting Program
We have turned our code to compute the area of a circle into a new program:
let radius = 4.2; let area = Math.PI * Math.pow(radius, 2); console.log("Area = " + area);
Notice that our editor, VS Code, helps us with JavaScript in all of the same ways as it helps with HTML and CSS, including auto-completion and access to documentation.
node.js is a standalone version of the JavaScript engine that drives Google Chrome. When we want to process a data file and create some output, node.js frees us from the browser.
We can also put code like this in an HTML script
and execute it as part of a web page. Let's learn how to do
that now, but in the context of a page we would like to modify.
To do that, let's first learn how to access elements
in a web page.
The Web Page as an Object
Why is all of this object talk, with data properties and methods, important to us as web developers? The browser gives us access to every web page as... a JavaScript object!
This image shows us this object for an arbitrary web page, along with the object's components.

JavaScript provides us many data properties and methods for
working with the parts of the page. One of the most useful
methods is document.querySelector()
, which accesses
an element on a page based on a CSS selector. Once we have an
element, we can use its data properties
innerText
and innerText
to see and
change the content of the element.
let heading = document.querySelector('h1'); heading // expand heading.querySelector('a') heading.innerText = "Tralfamadore"; // check... [* reload page! -- this is client side!!] heading.innerHTML = '<a href="https://en.wikipedia.org/">Hijacked!</a>';
This model of the web page is what we mean by the DOM, the domain object model.
Now let's use what we have learned about JavaScript and the DOM to modify a web page.
A Quick Exercise: The Road to St. Ives

Consider this children's rhyme:
As I was going to St. Ives, upon the road I met 7 wives.
Every wife had 7 sacks, and every sack had 7 cats, and every cat had 7 kittens.
Kittens, cats, sacks, and wives, how many were going to St. Ives?
Open a console
and write one or more lines of JavaScript to compute
the answer.
You can do this with variables or without
variables.
Building a Solution in the Console
This is a traditional English-language nursery rhyme with many variations, from the early 1700s. The numbers get big (for children) fast.
One expression will do the job:
7 + (7 * 7) + (7 * 7 * 7) + (7 * 7 * 7 * 7)
If all we need is the answer, once, this code is fine. In general, though, we would like for our code to be more expressive — that is, to "say what it means". That helps readers, including ourselves, understand it.
One way we can do that is to give names to the parts of the expression. There are four numbers in the sum, and the rhyme tells us that each means something particular. We can use variables to name them:
let wives = 7; let sacks = 7 * 7; let cats = 7 * 7 * 7; let kittens = 7 * 7 * 7 * 7; let total = wives + sacks + cats + kittens; total
Better! But those * 7
s also mean something! There
is a relationship between the number of wives and the number of
sacks, the number of sacks and the number of cats, and so on.
The statements don't say anything about that. We can fix it!
let wives = 7; let sacks = 7 * wives; let cats = 7 * sacks; let kittens = 7 * cats; let total = wives + sacks + cats + kittens; total
And we have our answer, in a clean, readable sequence of JavaScript statements.
Turning the Solution into a Script
We can do even better. We can incorporate scripts written in JavaScript directly into our HTML.
This web page presents our rhyme as a riddle for the viewer. Let's use our code to write the answer on the page.
First, we add a script tag to the bottom of the
body
.
... <script> </script> </body>
Then we copy the statements that compute the answer from the console and paste them into the script:
<script> let wives = 7; let sacks = 7 * wives; let cats = 7 * sacks; let kittens = 7 * cats; let total = wives + sacks + cats + kittens; </script>
But now how do we "see" the answer? Working in the console is
like having a conversation with an interpreter. The interpreter
reads an expression or statement from the user, evaluates it,
and prints the result. We can evaluate total
to
see the value 2800. Seeing the answer is built into the
process. Then the console waits for the user to enter another
expression.
A script is a set of explicit instructions, outside the console. To display anything, we have to do so explicitly!
In a traditional programming setting, the program would write
its answer to the user's computer screen. For example, in
Python, a script might say print(total)
. But we
are working inside a web browser: our computer and screen are
the browser. We show the user something within the browser.
JavaScript offers us a number of ways.
Earlier in the session
we learned how to use console.log()
to write values
to the console. We could add console.log(total);
to our script. Unfortunately, this requires the user to open up
the developer tools in order to see the answer, which is not
something most users want to do, or even know how to do.
But there is something better. As we also learned earlier in the session, we can use JavaScript to access content on a page and to modify content on a page.
So let's write our answer on the web page itself!
First, add a paragraph to the web page that reports the answer.
<p id="answer"> ... The answer is </p>
We give the paragraph an id so that our script can select it.
Then, add code to the script to select the paragraph, gets its text, and append the answer to the text.
// select the paragraph to display the result let target = document.querySelector("#answer"); // retrieve the current text of that paragraph let currentText = target.innerText; // add a space and the result to the current text // and assign to the paragraph target.innerText = currentText + " " + total;
Note the use of //
to create a comment in
JavaScript. The browser ignores all characters on the line
after the //
. We can also use the
/* ... */
form of multi-line comments we used in
CSS.
Reload the St. Ives page... Nice.
However, the script is now as long as the content of the web page. That makes it harder for readers to see the content and structure. As with CSS, we can move our code to an external script and link it in to our HTML.
Let's move the JavaScript code in our script to a separate file and modify the HTML page to load it in:
<script src="ives.js"></script>
This solution is even better, with a cleaner HTML file that is easier to read. The JavaScript code resides in a different file, befitting its different purpose.
Practice for later: Use a details
element to hide the answer until our young reader clicks the
widget. Style the element to draw in the reader.
One last item: Why did I place the script at the bottom of the
body
, and not at the top of the body
or even in the head
?
Move the script
element to the top of the
body
to see what happens.
The browser processes the elements of the page in order. If the
script appears at the top of the body, the browser will process
the script before it ever sees the paragraph with the
id
of "answer". The code intended to modify that
element has no effect, and the paragraph will be presented as it
appears in the document: "... The answer is".
(Later we will see cases where we do load scripts in the
head
element. These scripts include code that does
not refer to the HTML on the web until we invoke it.)
Yes, But.
Here is the final version of the HTML file and the JavaScript file.
All is good... until someone changes the story. The Wikipedia
page says that in some variants there are 9 wives, sacks, cats,
and kittens. In a nursery rhyme for children, we could use any
number of travelers: 6, 7, 8, 9, .... An Egyptian story circa
1650 BCE has a fifth category of traveler, of which
there are 7 * kittens
many!
Copying and pasting and changing the script becomes unbearable.
Fortunately, we can do better. And learning how will also prepare us to write code in a way that the browser will soon require. Let's pick up here in our next session.
Closing
Homework 7 will give you a chance to practice JavaScript on your own. It will go live tomorrow or early Saturday.
If you have not installed node.js yet, give it a try. Node can be a useful tool for working with JavaScript, including inside VS Code itself.
The midterm went well. Please make sure you know the names of the things we talk about all the time (elements, attributes, properties, ...). Otherwise, every conversation and every reading are a bit more work than they need to be.