We started this part of the course talking about using JavaScript to dynamically
generate HTML content.
We've been looking at JavaScript as a programming language and
it's features, but
now we're finally ready to start looking at how we can use it within HTML pages.
To understand how we can use JavaScript to access the HTML, and to dynamically
generate HTML, we have to start understanding what's known as the DOM.
The DOM is the Document Object Model,
which is a structured tree representation of the HTML page.
The browser takes the HTML that it receives and
converts it into this Document Object Model, or DOM, so
that it can be accessed within the browser by components such as our JavaScript code.
What does the DOM look like?
Well on the left side here we see some HTML, and
the right side we can see a visual representation of this tree.
The DOM tree matches the HTML elements or tags.
We can see at the top of the tree or the root of the tree is the body of the HTML.
And one of the elements that is part of the body is this div,
which is labeled header.
Within that div is some text, for instance, PennX at edX Home.
The middle div would be the same.
And in this far right we have the div called footer,
which has this Anonymous anchor or a tag.
And then that Anonymous anchor or a tag contains two other elements.
One of which is the href, where this link would take us, and
then the text that appears, which is Contact Us.
If you were to open up the Google Chrome console,
you would be able to inspect the DOM.
Here we would see it in a tree structure.
Notice that the missing tags in the sections are automatically added.
For instance, in the HTML on the left, there are no header tags, but
the browser would insert them into the DOM.
You'll also notice that this body tag is not matched here on the bottom,
but the browser knows that we need to end the body,
or close the body, before closing the HTML.
And it would insert the close body tag down here.
The browser console also allows us to expand and collapse
the different elements, as you would expect for instance in a file browser.
So why do we need the DOM?
Well remember, the HTML is specifying the structure of the content,
how the different elements relate to each other.
And the DOM allows us to programmatically access that structure using JavaScript.
So how then do we access the DOM in our JavaScript code?
We can start by using a global variable called document,
which represents the root of this tree structure.
From the document, we can access other elements in the tree, and
then we can manipulate them to change their HTML.
Here's a very simple example.
It's still an HTML page.
Within the HTML page we have this HTML tag, which is span.
Remember span, shown here, is just a small piece of the HTML.
And here I've labeled the span to have this id called dateTime.
Now we see the script tag, or the script element, in our HTML.
In this case, we're embedding the JavaScript code into our HTML page.
We'll specify a variable called dateTimeField.
We'll use this global document object.
We'll call its getElementById function, to get that HTML element using its ID.
The ID that we'll pass, or the argument that we'll pass, is dateTime.
And this will match, of course, the ID here for this span.
And then we can think that dateTimeField is now referring
to this element in the HTML.
That is, using the document and the DOM, we've retrieved that element by its ID,
and now we have a JavaScript object that refers to that HTML element.
We can set that HTML element's HTML content,
using its inner HTML property, which we'll set to a new Date.
This is going to use the date prototype,
which will return an object representing the current time and date.
Now we'll of course see many more examples of using JavaScript to manipulate
our HTML, but what if we wanted to store some data across multiple page requests?
We can use another global variable called localStorage.
Here we have some HTML at the top that includes a span, which we'll call report,
which is going to report the number of times we've visited this page.
Now I have my JavaScript, and
I'll create a variable called timesVisited, initially set to 0.
Then I'll access the localStorage global variable, and
I'll see if it has a property called timesVisited.
Now by default it will not have that property, but
that's okay, because when I access that property it will just return undefined.
Undefined is a false-y value, and so
this will return false and not go into the if statement here.
However if times visited has a truth-y value, for
instance a number, then it will go into the if statement.
And then what it will do is read from localStorage that value,
that property, convert it to an integer, and
store it here in my local variable called timesVisited.
Regardless of whether localStorage already had a field or
property called timesVisited,
we'll increment timesVisited to show that they've visited this page one more time.
And then we'll write this value, or we'll set the value, in localStorage.
Now, we wouldn't simply say, localStorage.timeVisited = whatever, but
rather, we'll use its setItem function and set this property to this value.
So all of that is just to read from localStorage and
update the number of times they visited the page.
Now let's update the HTML.
As we saw previously, we'll use the document global variable to get
the HTML element by its ID here using report, which will match this up here.
Now we have a JavaScript object that represents that HTML element,
and we can set its inner HTML content by setting
its inner HTML property to timesVisited.
Just one more additional feature that I threw in here,
cuz I thought it would be fun.
If we check the value of timesVisited, and for
instance say that it's greater than 10,
we can not only change as we saw here the innerHTML, the content, the words,
but we can also change the style.
Every HTML element will have a style property in JavaScript.
And in this case I can set its background color, for instance to red.
Now what if the contents that we want to store in localStorage is not
simply a number, but it is for instance an object.
Then we need to use what's known as Java Script Object Notation, or JSON.
JSON is a textual representation of a JavaScript object,
that can be stored as a string.
We're going to see how we use this later in the course, for
instance exchanging data between programs.
But it's simply a structured key value pairs of the fields or
properties of that object.
When I want to convert between the JSON representation and
an actual object, I can use one of these two functions.
If I have an object and
I want to convert it to a JSON string, I can use the stringify function.
And if I have a stringified JSON object, or string, and
I wanna convert it back to the original object, I can use parse.
This allows me to use objects in between page requests within localStorage.
I can use stringify to convert an object to JSON, and
I can use parse to convert the JSON back to the object.
Let's see one last example of how we would use stringify and
parse along with localStorage and the document and put everything together.
So here I have my HTML page.
At the top I wanna print the number of times that the user has
accessed this page.
And I also want to print the last time they accessed this page.
Within my JavaScript, I create a variable called timesVisited, which I'll set or
initialize to 0.
And I'll initialize this other variable lastVisitDate to never, so
that the first time they see the page it will say they've never visited it before.
Now I'll look in local storage to see if it has a property called lastVisit.
But unlike the previous example, lastVisit will not be a simple number,
but in this case it will be an object.
But as in the previous example,
if local storage does not have a lastVisit property, this will return undefined,
which is false-y, and it'll just skip this part of the code.
If it is defined, then we'll go into this part of the code,
we'll get that JSON representation out of localStorage.
We'll use the JSON.parse function to return this object,
which we'll call lastVisit.
lastVisit will have a numVisits property, and
we'll set timesVisited = lastVisit.numVisits.
Likewise, lastVisit will have a date property,
we'll set lastVisitDate equal to that value.
So all of this code here is just reading this JSON object out of localStorage.
Now I'm ready to modify my HTML content.
I'll do that using this line here, starting with the document.
I'll call its getElementById function and
pass the argument lastVisitDate, which is this span up here.
I'll set its innerHTML to the lastVisitDate.
The lastVisitDate will either be the value that came out of the JSON object or never.
Then I'll increment timesVisited.
timesVisited will either be the value that came out of the JSON object or 0.
And then I'll update my HTML.
Again starting with the document, I'll get this element by its ID,
I'll get the report span, which is up here.
I'll set its innerHTML to timesVisited.
And the last thing I need to do is then store the data back in localStorage,
now that I've updated it.
We haven't seen this notation before, but
I can create an empty object just by using the empty curly braces here.
I can give it a date property and set it to what is the current date and time.
I can set it's numVisits property to whatever the value of times visited is.
And lastly, I can take that object, stringfy it,
and then store it in localStorage.
In summary, we've seen here now how JavaScript can use the DOM to retrieve and
modify HTML elements.
They can use the getElementByID function to return a specific HTML element,
and then modify it using its innerHTML property or its style property.
We can use the localStorage to save values across page requests.
And even if those values that we want to store are objects,
we can convert it to a string representation using JSON.
We've only started to scratch the surface of how we can use JavaScript to
modify HTML.
We're going to see more of that in the next few lessons.