BRIAN YU: All right. So far, we've been able to create and
style web pages using HTML and CSS. But HTML and CSS really just describe
what the web page looks like. In order to create more
interactive web pages, we're going to need to introduce a
programming language that will give us access to programming constructs--
things like loops, and conditions, and functions. And the programming language
we'll take a look at today is JavaScript, a programming
language that our web browsers are able to know, and interpret, and
understand so the JavaScript code can actually run inside of the
browser alongside a web page that you might be displaying to a user. JavaScript has a lot of similarities
to programming languages like C, which you're already familiar with. So let's take a look at some of the
similarities and differences between C and JavaScript, and then taking
a look at how we can actually use JavaScript inside of our web pages
to create even more interactive web pages. So in C, for example, if you wanted to
declare a variable that was an integer, you might have had code that looked
a little something like this. int counter = 0. Counter is the name of the variable,
and int, in this case, is the type. In JavaScript, we would express the same
idea using let counter = 0, semicolon. Very similar syntax. The only difference is that we've
replaced int, the type in C, with just the keyword let in JavaScript. We use let counter = 0 to mean counter
is a variable that is set to 0. And JavaScript doesn't
require us to specify, for every variable, what
its type necessarily is. JavaScript just knows, when it
sees a 0, that that is an integer. And whereas in C, you might have
needed to declare a floating point value using something like float value
equals, or a Boolean value using, like, bool flag equals something, in
JavaScript, rather than using int, or float, or bool, we're just going
to use let for everything to declare a new value, regardless of what
type that value actually is. If we want to manipulate
a variable in JavaScript, it's identical to how
we might manipulate that variable in C. In C, we could say
something like counter = counter + 1. And that exact same syntax
works in JavaScript as well. Likewise, a lot of the shorthand
that we introduced in C in order to increment variables also
applies to JavaScript as well. Whereas in C, we could say counter
+= 1, in JavaScript, same idea. If we want to increase
counter by 1, counter =+ 1. And just as in C, counter++
does the exact same thing-- incrementing a variable by 1. In JavaScript, counter++ also
does the exact same thing-- incrementing that counter variable by 1. In C, this was an example
of a condition that checked, for example, if x was less than y. And in JavaScript, that
syntax is identical. If, and then in parentheses, the
Boolean expression we want to check-- if x is less than y-- and then curly braces to enclose
the body of that if condition. If we want to add an else case
in C, we just added else and then another set of curly braces. And in JavaScript, again,
it's exactly the same thing. If, and then a set of curly
braces, and then else, and then yet another set of curly braces. And in C, we could add else if's and
else if's within those conditions. And in JavaScript, we can
also do the same exact thing. A while loop in C-- this was
a loop that ran forever-- was just while true. And in JavaScript, while
loops look identical as well. It's while, and then in parentheses,
whatever the condition is, whether it's true, to create an infinite
loop, or some other Boolean expression that might only be
true a finite number of times. And in C, a for loop that ran 50
times, for example, looked like this. We had for int i = 0, i is less than 50,
i++, and then the body of the for loop. In JavaScript, it's going
to look very, very similar. But just as when we declared
variables for the first time in C, we didn't need to specify that counter
was an int, for example, in JavaScript, the same thing is going to
hold true for a for loop. Here, we're going to say that, for
let i = 0, i is less than 50, i++. Again, the only change here is
that we've replaced int with let, and we'll use let to introduce
new variables for the first time. In C, when we had decided that we
wanted to create a new function, like this cough function, that took
an integer parameter called n and had a return type of void, meaning there was
no return type, this is how we did it. In JavaScript, it's going to be similar. But again, we don't need to
be as precise about the types when we're declaring a
function for the first time. Rather than specifying the
return type of a function before we give the name
of the function, we're just going to use the word function. So the JavaScript knows that
cough, in this case, is a function. The parameter, or the input, to
the function is an integer n. But in JavaScript, again, we don't
need to specify that n is an integer. We just need to specify that there
will be an input to this function that is called n. And there are a couple of other
differences between JavaScript and C as well. But as you might glean from just
looking at these examples so far, the syntax is very, very similar. And if you're familiar with C, and
the idea of loops and conditions and functions in C,
JavaScript is going to look very similar in terms of the way
that its programming constructs are expressed in syntax as well. So why are we thinking
about JavaScript, and what is JavaScript going to enable us
to do in the context of web pages? Well, to start, let's take
a look at a simple web page. Here's a web page we've
seen before written in HTML. And again, we have an HTML tag, inside
of which is a head tag, inside of which is a title. And then we also have a body of
the HTML page, which, in this case, is just going to display "Hello, world!" This is the way we would express this
very basic web page using just text-- HTML syntax. But one way to think
about this particular page is by expressing it as a
tree, a structure of elements connected to other elements. And so the equivalent tree
that we would use here would look something like this. This is a graphical
representation of the same page that you see on the left
expressed just using HTML text. Up at the top, we have a
rectangle that says html, representing the HTML element
that represents this whole page. And nested within the HTML
element are two elements expressed as the children
of the HTML node inside of this tree on the right-hand side. So html has a head child representing
the head element inside of it and a body child representing
the body element inside of it, which corresponds to the
idea that if you look at the HTML on the left, inside
of the two HTML tags, we have a head tag and a body tag. What's inside of the head tag? Well, we see the title, which
just contains the word hello. And then inside of the body, we
just have the text "Hello, world!" And so this, what we see
on the right hand side, is a graphical
representation, or a model, of what this web page
actually looks like-- of elements nested within other
elements nested within other elements. And this model we call the Document
Object Model, otherwise known as the DOM. And what makes JavaScript
powerful is that JavaScript, when run inside of our web browser,
has the ability to manipulate the DOM. It has the ability to look
at the Document Object Model, the structure of the
web page, extract parts of it, replace parts of it,
and update parts of it so that we can really create interactive
web pages where we can write code that is able to look at the structure of
this page, make decisions based on that, and update the structure
of the page in response. And so that's what we'll
take a look at-- examples of using JavaScript to be able to
create more interactive web pages. So let's first take a
look at a simple example and see how we could just introduce
JavaScript into our web page. I'll go ahead and go into
CS50 IDE, where here I have an index.html file
that just says Hello, world! Inside the body and has a
title of Hello!, in this case. What can we add to this in order to
add some additional functionality to this web page? Well, we're going to
add some JavaScript. And the way we're going to do that
is, inside the head section of the web page, I'm going to add a
script tag, inside of which, I could include any
JavaScript code that I want. So in C, if we wanted
to do something simple like print "Hello,
world!" to the terminal, we would do something
like printf hello world. In JavaScript, what we'll
do instead, since we're working in the world
of a web page, is let's try and create an alert that will
display on that web page just to display some text, for example. I'll go ahead and, inside of the
script section of the web page, call a function called alert,
which is built into JavaScript. And then the argument to it will
be a string, which, in this case, will be just Hello! And then ending that
line with a semicolon. You'll notice here that I've surrounded
Hello! in single quotation marks. Strings in JavaScript can be
surrounded by single quotation marks or double quotation marks. Either is OK. Just be sure to be
consistent with however you're defining your strings here. All right. So we've added some code to the
script section of our web page that we're hoping is just going to
display an alert that says hello. Let's try it out. In order to view this web page,
we'll start up an HTTP server. And we can do that by going back into
CS50 IDE and running http-server. Here's the URL that we get. And if we go to that URL, we'll see
that we have an index.html file there. And if I click on index.html, what I
see is an alert that, in this case, just says, "Hello!" That was the alert that I included
in the script section of my web page. I click OK. And all right, here is the page
that now just says, "Hello, world." So there we have it--
our first little bit of JavaScript using the
alert function that just says hello anytime we visit this web page. But let's now try and make our web
page a little bit more interactive so that it doesn't say hello every
time we load the web page, but maybe when we click a button,
for instance, to submit a form or something. So let's go back to CS50 IDE. And inside of the body of my
page now, I'll add a form. So I'll get rid of Hello,
world!, and I'll add a form. And that form is just going to
have an input whose type is submit. And recall that if I have a
form whose input type is submit, that's going to have the
effect of just creating a button on my web page where
I can click on that button to submit the form. And what I want to do now
is, when I submit this form, I would like to run some code that is
going to display an alert that says, 'Hello!' for example. Well, right now, every
time I load this page, I'm seeing this alert
that says hello to me, because when my browser
is reading index.html, it's reading from top to bottom. It comes across this line that says
alert('Hello!'), and so it displays an alert that says, "Hello!" to the user. So what I can do instead is,
instead of just putting it directly inside the script
section of my page, I'll go ahead and put the alert
inside of a function. So I create a function-- again, just using the keyword
function in JavaScript-- and I'll call that function
greet, for example, because I want to greet the user. And I'll take the line that says
alert('Hello!'), and I'll put that line inside of that function. So now I have a function called greet. And when I run the greet
function, it's going to generate an alert that says "Hello!" And now what I'd like to do is make
it so that when I submit the form, it is going to call that greet function. How do I do that? Well, it turns out that
the form element has an attribute called onsubmit
that determines what should happen when I submit this form. And what would I like the form to do? Well, when I submit the form, I'd
like to call the greet function. So I'll call greet by
typing "greet" followed by parentheses-- there's no input to
the function-- and then a semicolon. And then I'll need to
add one additional line. I'll need to add return false. The reason for this is that forms, by
default, when you try to submit a form, are going to try and submit to a new
web page and load that new web page. And I don't want that
behavior to happen. And so return false just
here tells the web browser, don't do what you would
normally do, which is submit the form to another
page and load the web page. Just go ahead and do nothing
else after you greet the user. So we're going to call the greet
function and then return false. Let's try it out. I'll go back to the web
page, refresh the web page. And here, I see a button called Submit. And this is the button that's
going to submit this HTML form. And when I click on the Submit button,
it's going to call the greet function. And there we have it, an
alert that now says "Hello!" But let's now try and make this
program a little bit more interactive. Rather than just saying
hello, let's see if we can prompt the user to type
in their name, for example, and say hello to that person. for instance. I'll press OK, and let's go back here. What might we want to add to this form? Well, I'll add another input
field whose type is text. And by creating an input
field whose type is text, the goal here is that I want the user
to be able to type in their name, for example, and then
submit the form, so that we can say hello to Brian,
or hello to David, for example. So let's go back. Refresh the page. All right. Here we have an input field now
where I can type in my name. I can type in Brian
and then click Submit. But all right. It still just says hello,
because my JavaScript code is not using the fact that I've typed
in my name into this field. It's not doing anything
with that information. What I'd like to do is somehow
update my JavaScript code so it looks into my web page, looks at
the DOM, the structure of the web page, looks for that text
field and figures out what value that text
field currently holds, what name was typed
into that text field, so that my alert can display
hello to that person, for example. So let's give that a try and
figure out how we might do that. We'll go back to our HTML page. And what I'd like to
do inside of my greet function is somehow figure out what
the name that was typed in is-- maybe defining it and placing it
inside of a variable, for example. So I might want to say, let name equal. And somehow, I need to extract from this
page whatever it is that the user typed in into the input field. How am I going to do that? Well, the first thing I'll need
to do is take this input field-- this input whose type is text-- and I need to give it a
unique identifier, or an ID, that's going to be some name that I can
use to reference this particular HTML element so that in my JavaScript
code, I can try and extract that piece of information. So I'll go ahead and give this
input field an ID of name. And an ID is just a
unique identifier that I can apply as an attribute
to any HTML element in my page that will allow me
to reference a particular HTML element by whatever name
I happen to give it. And in this case, I've given this input
field-- this text-based input field-- an ID of name. Now, how do I access that
particular HTML element from inside of my JavaScript code? Well, there's a function in JavaScript
called document.querySelector. And the document.querySelector
function is going to try and find an HTML element
that matches a particular query. It's effectively going to let me
search through the entire HTML page looking for a particular element
and then return it back to me. And in this case, the
element I want to search for is an HTML element whose ID is name. And in order to search for that, the
syntax that I'll use is hashtag name. This hashtag, or the pound
symbol, means, look for something with this particular ID. And what I'm saying
when I say hashtag name is that I'm looking for
something with an ID of name. So all right. I've run
document.querySelector('#name') to say, look for something inside my
HTML page that has an ID of name. And what I'd like to do is
not get the whole input field, but get the value of the
input field-- the thing that the user has actually
typed in to this input field. And so all right. In order to do that,
document.document.querySelector is going to give me
back this HTML element. And it turns out that the HTML
element has an attribute called value that represents what it is the
user has typed in to the text field, for example. And so if I say
document.querySelector('#name').value, what that's going to
do is it's going to-- document.querySelector will search
through the page for an HTML element whose ID is name, which means it's
going to find this input field. And then when I say .value, it's going
to take that input field and get its value-- whatever it is that I
actually typed in to that HTML field. And I'm saving that result inside
of a variable, which, in this case, is just called name. So all right. Now I can say, Hello comma. And then in order to join two
strings together, in JavaScript, I can just use plus for that
to join two strings together. I'll say 'Hello, ' + name. And we'll add an exclamation
point at the end of that. So what have I done here? I've defined a variable
called name, which I'm setting equal to whatever it is
the user typed into that name field. And then I'm displaying an alert that
says hello to that particular name. Let's give this a try. I'll go back to the HTML page. I'll refresh it. And now if I go to the input
field and type in my name-- Brian-- and press Submit-- all right. Now the alert that gets
displayed says, "Hello, Brian!" If I press OK and try another name-- I'll type in Emma, for example-- press Submit, and now the form gives
me an alert that says, "Hello, Emma." So I've been able to make this program
a little bit more dynamic, a little bit more interactive. Now, what might happen if I
don't include anything at all? If I leave the input field
blank and then I press Submit? Well, now it says, Hello, comma,
and then an exclamation point. All right. It left it blank, because when
it tried to extract the name, there was no text inside
of that input text field. And so name-- that variable-- was just
set to the empty string, for example. So how might I go about fixing that? Well, let's just add a condition. This is JavaScript, a
programming language that has conditions, and functions, and
loops, and variables just like C does. So I can say, all right. If name is equal to-- and in JavaScript, I can use a triple
equal sign to denote that something is exactly equal to something-- so,
slightly different than what you saw in C. If name is equal
to the empty string-- in other words, if it's
just not equal to anything-- then I'll go ahead and set name
equal to world, for example. So if nobody types in anything,
I'll replace the name variable with the world. What's the result of that going to be? Well, if I refresh the
page and type in Emma, it's still going to say, "Hello, Emma!" But now, if I leave the input
field blank and press Submit, now the message says, "Hello, world!" It detected that the string I
typed in was the empty string. There was nothing in the text field. And so that condition became true. And so the result was that the
variable name was set equal to world, and we displayed an alert
that said, "Hello, world!" All right. So we've seen now that
using JavaScript, we can create web pages that are more
interactive than the types of pages we've been able to create before. We've been able to
actually write code that looks at the HTML content of the
page, looking at things like, what did the user type into
this text field, for instance? In order to use that information
to display an alert, for example. And we used document.querySelector
to read information from the DOM, the Document Object Model, or that
structure that makes up our web page. But in addition to reading
information from the DOM, we can also update the
DOM-- actually change the content of the web page using
JavaScript as the programming language that we're using to do this. How could we do that? Well, let's take a look
at this example again. Maybe instead of displaying an alert
that says hello to someone's name, maybe we could actually
update the body of the page in order to display that information. So I'll go ahead and add
to the body of my web page a div, which you'll recall is
just a section of my web page that I can give a name later. And inside of this div, I'll
just say hello for right now. And what I'd like to do is,
when someone submits the form, I would like to update this
section of the web page. So instead of just saying hello, it's
going to say hello to the person, for instance. How am I going to do that? Well, just as before,
my JavaScript code needs to have some unique way of referencing
this particular HTML element. And in the case of this
input field, we did that by giving that input
field an ID of name-- some unique identifier
that I could use inside of my JavaScript code to reference
this particular HTML element. And we'll do the same thing here. We'll give this div an ID, which,
in this case, I'll just call result. It's going to be the result of
running this greet function. And now, up here, inside
of my greet function, instead of displaying an alert
that says hello to a name, I'll go ahead and instead say,
let's run document.querySelector, and, again, using the hashtag,
or pound symbol, to say, get me the element whose ID is
result. document.querySelector result to say, get me the
element whose ID is result. And rather than just
read the data, I would like to actually change the HTML
that is inside of that HTML element. And in order to do that, I can use the
.innerHTML property of the HTML element that will give me access to the HTML
that's contained within this HTML element. So I'm getting the HTML
element whose ID is result. And I can set the innerHTML
equal to whatever I want. And in this case, I'll set it equal
to Hello, comma, and then the name, and then an exclamation point. So I'm saying hello
to whoever the name is and replacing the inner
HTML out of the div whose ID is result using
this line here on line 14. Let's give it a try. I'll go back to the page,
and I'll refresh the page. And you'll notice here
that I have a form that gives me a place to type in a
name as well as a Submit button. And beneath that, I see the word hello. That's the current content
of my div, who ID is result. Now, though, if I type in a name, like
Emma, and click Submit, you'll notice the page actually changes. And now it says, "Hello,
Emma!", because I'm running JavaScript code that found
that particular div inside of my page, and it updated the innerHTML to
now say hello to Emma instead. All right. So now using JavaScript,
we have the ability to use document.querySelector
to access parts of the web page in order to read data about what
the user has typed in, for instance. And we can also do the opposite. We can write more
information to the web page, updating the web page in
response to what users type in, or in response to button
presses, and so forth. Let's take a look at one other
example that we'll use that idea, but also add some variables
into the mix as well. I'll create a new file that, in this
case, I'll just call counter.html. And the general structure, again,
will be pretty similar to index.html. So I'll copy it in
here for now, but I'll clear out the contents of the script. And what I want to do now
is just create a web page that's going to have some
sort of counter that's going to let me increment the counter-- 0, 1, 2, 3, 4, 5, et cetera, et cetera. So inside the div, to
start, I'll just go ahead and include 0 as the starting value. And inside of my form, I don't
need an input field anymore, but I will have a Submit button
that will let me submit this. And when I submit the form, I'm going
to call a function called increment, for example. All right. So inside the script
section of my website now, the first thing I'm going
to include is a variable that's actually going to keep track
of whatever I'm currently counting to. And I'll create a variable called
counter by saying, let counter = 0. And now, what should my
function increment actually do? Well, the first thing I'll
have my function increment do is increment the counter-- counter++ to say, take the value
of counter and increase it by 1-- so to go from 0 to 1 to
2, so on and so forth. And next, I'll say, go ahead
and use document.querySelector to get the element whose ID is
result, and update its inner HTML to be equal to whatever the
counter is currently equal to. So my increment function
is doing two things-- step one, increment the counter
variable, and step two, update the DOM. Update the innerHTML of this
div, whose ID is result, in order to update it to whatever the current
value of the counter variable actually is. All right. So if I load counter.html,
here's what I see-- a Submit button that will let me submit
this form, and currently, just 0, the current value of the counter. But if I click the Submit button,
you'll notice the value increases to 1. I click it again, it increases to 2. I click it again, it goes
to 3, so on and so forth. I'm able to use this form to
trigger a function that updates the variable counter and then
updates the DOM-- updates this page to now display that resulting number. And it turns out that,
inside my web browser, I can actually access
these values of variables and call functions from
inside the browser. If I go to View,
Developer, Developer Tools, I can actually access
the JavaScript console by going to the Console
tab and Google Chrome where I could type in
something like counter to get the current value of the counter
variable, which, in this case, is 3. In addition to that, I
can call functions, too. I can call the increment function. And when I run that, you'll notice the
value of the counter went from 3 to 4. Call increment again in
order to go from 4 to 5. And in addition to viewing
variables and calling functions, I can modify variables as well. I can say, all right. Let's go ahead and set counter
equal to 27, for example. When I did that, though, notice
the number didn't change to 27. It's still 5, because I haven't
actually updated the DOM. I haven't updated any content of this
page to say, set this div equal to 27. It just currently says 5. But notice that now if I
do click the Submit button, it's going to increment the
value of counter from 27 to 28. And now that value does
get displayed on my page. So I can use the
JavaScript console to be able to manipulate values of
variables, call functions. And generally, this can
be a useful debugging tool as well, if you want to see
what the value of a variable is, for example, from inside
of the JavaScript console. And if you have syntax errors or
other bugs that are happening inside of your code, oftentimes, you'll
see error messages show up in this JavaScript console as well. So it can often be a good
place to look if you're finding that your JavaScript
isn't quite working. All right. Let's take a look now at
another example of what we can do using JavaScript
to dynamically change the content of the page-- in particular, changing the
style of the page in addition to just what the content
of the page actually is. I'll create a new file that
I'll call background.html. And inside of background.html, we'll
copy the same general structure as the examples previously, but
now we'll replace the script and replace the body with,
instead, three buttons. Create a button that says R, a button
that says G, and a button that says B, standing for Red, Green, and Blue. And these button HTML elements--
if I load the page by-- I'll close out of the console, and
just going to background.html-- these are just going to show up-- I'll save the page, refresh the page-- these are just going to show up as
three buttons-- a button called R, a button called G, a button called B. And what I'd like to have happen is
for these buttons to do something. So how can I make that happen? Well, the first thing is that I'll need
to give a unique identifier to each of these buttons. I'll go ahead and give this button an
ID of red, this button an ID of green, and this button an ID of blue. So what now can I then do
inside of my JavaScript code in order to manipulate these values? Well, what I might want
to happen, for example, is, when I click on the
red button, I'd like to change the whole background
color of the body of my web page entirely to red, for instance. How might I do that? Well, the first thing you'll
imagine I'll need to do is I'll need to access the
button whose ID is red. And I can do that again by saying,
document.querySelector('#red') to say, get me the button or the
element whose ID is red. And on that button, I can add an
onclick attribute to it to say, here's what should happen when
you click on the red button. What should happen? Well, when you click on a
button, presumably, some function is going to run. And so the next thing
I'm going to include is going to be a bit of new syntax. But I'm going to say function,
and then just put two parentheses, and then open curly brace,
curly brace to say, here, now, is the body of the
function that is going to run when I click on the red button. Now, notice that this
function differs a little bit from the greet and the
increment functions that we've seen already insofar
as it doesn't have a name. I haven't given a name to the
function after the keyword function. And this, in JavaScript, is what
we call an anonymous function. Functions in JavaScript
don't necessarily need names, because, in this case,
I'm just saying, here is a function. And I'm setting that function equal to-- and setting it equal to this
variable onclick this attribute of the red button so that when
you click on the red button, this is the function
that is going to run. And that function doesn't need a name. The red button is just going to
know that when it is clicked on, this is the function
that is going to run. So all right. What would I like for this button to do? Well, I'd like to get the body
of the page and change its style, change the background color of the body. How do I get the body of the page? Well, I could add an ID to the body
and say, body this is the ID, is body. But that seems like a little
more than I need to do, because there's only
one body of the page. And it turns out that when I
use document.querySelector, there are a couple of different
ways that I can run queries. I could use the hash mark to say, get
something with this particular ID. You could also use dot
followed by the name of a class if you wanted to look for something
with a particular class name. But in this case, I can
just use the word body to look for an HTML
tag that is named body. And in this case,
there's only one, which works, because query selector is only
going to return one HTML element. So here, I'm looking for an element
that is the body of the page, and I would like to change
the style of the page. And what part of the
style do I want to change? I want to change the background color. And I'll set the background
color equal to red. All right. Let's give this a try. I'll go back to the page,
I'll refresh the page, and I'll click on R. And all right. Nothing seems to happen. The background didn't change to red. Why might that be? So again, whenever you
run into issues like this, oftentimes, it's a good idea to
open up the JavaScript console, see what might be going wrong. And in this case, I'll go to
View, Developer, Developer Tools. And all right. I'm getting an uncaught typeerror-- cannot set property onclick of
null in background.html line 7. So let's go to background.html,
take a look at line 7, and see if we can figure
out what's going wrong. We'll go back here. And on line 7, I'm saying, find
me the element whose ID is red, and add an onclick
attribute to that element. But it's giving me an error that
says that you can't add an onclick attribute to null, which seems to
suggest that my JavaScript code isn't able to find an HTML
element whose ID is red, even though you and I can
obviously see that, right here-- here's a button whose ID is red. So that should be the HTML element that
my JavaScript code is able to find. So why isn't it able to
find it in this case? Well, recall that JavaScript, much
like other programming languages, reads our code from top to bottom. And as we go through background.html
from top to bottom, when we hit line 7, we're going to be looking for
an element whose ID is red. But the button whose ID is red doesn't
get introduced for a couple more lines, until like 13. So as of line 7, JavaScript isn't able
to find an element whose ID is red. How can we solve this problem? Well, there are a couple of ways. One thing is we could add to
the script section of our page another function that basically is
waiting for everything in the page to load before we
actually run this code. But a simpler way for
now is just to say, let's take this whole script section
of the web page and move it to after we've defined
all of these buttons. So we're going to define button
red, button green, button blue. And now, here's the script
section of my web page that's going to say, when
the red button is clicked, go ahead and change the background
color to be red, in this case. Let's try it. I'll close the console,
refresh the page. And now, when I click
on the R button for red, you'll see the entire
background of the page-- that changes to red. Now, the green and blue buttons
don't do anything just yet, but we can fix that
using very similar logic. I can say document.querySelect
or('#green').onclick. When I click on the green button,
I would like to take the body, change the style, change
the background color, and set the background color to green. And likewise, when I do
document.querySelector('#blue'), meaning when I click
on the blue button-- onclick-- I would like
to run this function that is now going to look for the
body and change the style, changing the background color to blue. So now if I refresh the page, the red
button changes the background to red, the green button changes
the background to green, and the blue button changes
the background to blue. Of course, you might notice that there's
a fair bit of repetition of code here. I've repeated, essentially,
the same idea multiple times. And there are a couple of ways
you might want to clean this up. One initial thing you might want
to do is notice that I'm calling document.querySelector('body')
over and over and over again. I could just create a
variable-- say, for example, let body =
document.querySelector('body'). And now, instead of using
document.querySelector('body') in three places, I could replace this
with the name of that variable. I could just say
body.style.backgroundColor here. And then likewise, here,
replace that with body and replace this with body as well
just to simplify the code a little bit and avoid needing to repeat as much. But there is still some
amount of repetition that's happening here as well. So all right. What have we done here? We've been able to create what we call
events that are being listened for. We added a event handler to our
particular buttons-- the red button, the green button, and the blue buttons-- where the buttons are listening
for a particular event-- in this case, the onclick event, such
that when the button is clicked on, that's going to result in running some
particular function-- in this case, this function here that is
going to change this background color of the body to red. And it turns out there are a
whole bunch of other events that you can listen for. You can listen for onclick,
but also things like ondrag, on keypress, on keydown, keyup-- many different events that
might happen as the user is interacting with your page. And you can add those event
handlers to particular HTML elements such that, when your user interacts
with your web page in a particular way, you can have some function
run that is going to perform some behavior on your web page. So let's actually take a look
at some of those other events that we can listen for in order
to modify the page in other ways. All right. I'll go ahead and create a new
file that I'll call size.html. And the general structure will be
very similar to this background color program that I wrote that was
allowing me to change the background color of the page. But now, I'll remove
this existing script. Instead of the three buttons, I'm
going to create a select element. And a select HTML
element is going to have the effect of creating, effectively, a
drop-down menu from which I can choose from a number of possible options. So I'll create a new option
that says large text, and I'll create another
option that says medium text, and I'll create another
option that says small text. Effectively, I'm going to allow myself
to choose a font size, for example, for a paragraph. And for good measure,
I'll add a paragraph at the top of the body that says,
this is some text, for example. Now, it turns out that
every option, if I want to be able to access
that option, needs a value-- some way of identifying
which option was selected. So I'll give this
option a value of large. I'll give this one a
value of initial, which is just a word in CSS that represents
the initial size of a particular font. And then I'll add for this
one a value of small to say, here's the small value of
the font size for the text. Now, inside of the script
section [INAUDIBLE] my web page, what I'd like
to happen is that, whenever I change the value of this
select drop-down menu, I would like to result
in some function that gets run that changes the font
size of some text [? here. ?] And because initial is the initial value
that the font size is going to take on, I'll go ahead and add an additional
attribute to this select option, which is selected, which is the
attribute that's going to say, by default, select
medium text, which has a value of initial, which
will be the initial font size that my paragraph has. So inside of my JavaScript code
now, I'll do document.querySelector. And I'm just going to look
for a select HTML element. I haven't given it an ID. Because there's only one
select element, I can just say select to get that HTML element. And I want to add an event handler here. Instead of onclick, which
we did with the buttons, to say when you click on
a particular button, here, I'll use an additional
attribute called onchange that will be fired any time I change
the value of this select drop-down menu. When the select drop-down is changed,
I'll go ahead and run this function. And what I would like for the
function to do is take the paragraph, change the style of the
paragraph, change its font size. But what do we set the
font size equal to? Well, what I'd like to
do is I'd like to set the font size equal to whichever value
was chosen from the select dropdown. But how do I do that? Well, it turns out that when
I'm inside of a function that gets called by an event handler,
like the onchange event handler, I have access to a special
JavaScript keyword called this. And this is a keyword that's
just going to represent, in this case, what it is the triggered
the onchange event-- what caused the onchange event to start firing. And so if I say this.value,
what's going to happen is it's going to get me the value of the
thing that triggered the event, which, in this case, was the select drop-down. And so this .value will give me access
to which of the options I actually selected-- was it large,
or initial, or small? And I want to update the font size
of the paragraph to reflect that. All right. Let's take a look at
this now in practice. I'll go to size.html. And here, we have some
text and a drop-down, which, initially, is set to
medium text, the initial value for the font size of the text. If I now take it and change it
to small text, for instance, you'll see the font size changes. Now, this is some text appears smaller. Because when I changed the
value of the select drop-down, that triggered my function
to run, which looked at the value of the select
drop-down, which, in this case, is the word small, and updated,
the style of the paragraph to reflect that new value. If I take the drop-down and
again change it to large text, for example, now the text is large. And if I change it back to medium,
it goes back to its initial value. So I'm now able to use buttons,
and drop-downs, and other ways of interacting with my web page in order
to actually change the content of what I see on that web page, too. All right. So using JavaScript,
we've been able to create web pages that respond to user events-- users clicking on a button, or a
form, or choosing a different option from a select drop-down menu. But what if we wanted to
update the page in other ways, too, automating this process,
and maybe updating the page every some number of seconds
or milliseconds, for example? In the early days of
the web, it was pretty popular to have these
blinking HTML elements that would display, and disappear,
and display, and disappear. So let's try to recreate that
effect using JavaScript now in an automated way. I'll go back and create a new
file that I'll call blink.html. This, again, will just be
an HTML file in English. And I'll give it a title of blink. And inside the body of the page, it will
just say, "Hello, world!", for example. And what I'd like to happen is for
the body to display, and disappear, and display, and disappear. How might I go about doing that? Well, let me add some JavaScript code
in the script section of my web page. But in this case, I'll just
create a function called blink. How is this going to work? Well, let me first get the body. How do I get the body of the page? Well, I can define a
variable called body, which is equal to
document.querySelector('body'). That will ask for the body of the
HTML page and return back to me that HTML element. And it turns out that HTML elements--
we can access their style as we've seen before using body.style. But I'm going to check
if body.style.visibility is equal to hidden, meaning
not currently being shown. Well, then, let me change
body.style.visibility to be equal to visible instead. So if the body is currently hidden,
let me change it to visible. And otherwise, I'll go ahead
and say, style.body.visibility set equal to hidden. So if the body is currently
hidden, we'll change it to visible. If the body is currently visible,
we'll change it to hidden. And now what I'd like to have
happen is for this function blink to be called every some number
of milliseconds, for example. So it's called again, and
again, and again, and again. How might I do that? Well, there's a function
called window.setInterval that lets me set an
interval on the window so that a function is run every
some number of milliseconds. This function takes two arguments. The first argument is, what
function do I want to run? And I want to run the blink
function, in this case. And the second argument is, how
often should we run this function? How many milliseconds apart
should these functions be called? And here, I want to run this
function every 500 milliseconds, let's say-- every half a
second, in other words. And this is a note to myself. Just as in C, you could add comments
to code by using two slashes. In JavaScript, you
can do the same thing. I'll just make a note
that, here, we're going to blink every 500
milliseconds as a note to myself of what it is that's
happening in this part of the code. I'll go ahead and go back
and go to blink.html. And now what you'll see is
a blinking "Hello, world!" Every half second, the
blink function is called. It disappears, and reappears,
and disappears again. So all right. I've been able to recreate
this blink functionality using a fair bit of JavaScript code, even
though the HTML content of my page is very, very small. And so here, too, is an opportunity
to begin to factor things out. In the same way that when
we were talking about CSS, it would often make sense to take CSS
and move it into a separate file just for cleanliness. So we can separate
our HTML from our CSS. We can do the same thing with JavaScript
as well-- taking some JavaScript code, separating it into a different file,
and then just referencing it inside of this HTML file. So how might I go about doing that? Well, I'll create a new file
that I'll just call blink.js. You could call it anything you want. And here, I'll just include
the entire JavaScript content of this blink.html page. Whatever was originally the
JavaScript inside of blink.html will now be the JavaScript inside of
blink.js-- defining a function called blink, and then setting an interval
to blink every 500 milliseconds. And now, inside my
HTML page, rather than a script tag inside of which with
all the JavaScript, I'll go ahead and just say script,
source equals blink.js. I'm referencing what JavaScript
file is the JavaScript that I want to include in
this section of the web page, very similar to the way that I was
able to include a CSS file in order to include that information
inside my web page as well. And now blink.html is a
whole bunch shorter, right? It's just the head
[INAUDIBLE] displays the title as well as defining what
JavaScript file should I run when you load this web page? And then the body of the web
page is just "Hello, world!" And blink.js now contains
all of the JavaScript code that is actually going to run. So just a little bit more organized now. And if I go back to the
page and refresh the page, you'll notice it's behaving
the exact same way. It's doing the exact same thing. I've just separated the
JavaScript into a different file, and now I'm including it inside of
the HTML file that I'm using now. All right. So as one last example, let's
take a look at some other features that JavaScript gives us access to. We've only just barely
scratched the surface. But to take a look at
some other things, I'll create a new file
called geolocation.html. And inside of geolocation.html,
I'll go ahead and start up the basic structure of the web page. I'll go ahead and add a script
tag to the body of my page where I would like to get
the user's current location. It turns out there's
a way to do this using JavaScript that uses something
called navigator.geolocatio n.getCurrentPosition. And this is a function that
is going to access geolocation services from my computer and
try and get my current position-- my current latitude and longitude. And when it does, the
argument to this function is another function, which is
what's called a callback function-- the function that should be called
after we've gotten the current position. And so this is just going
to be a function that takes an argument called position. And so inside of this
function, now, which is the argument to another function,
which is a little bit confusing, here is the code that
I can now run, which is going to determine what should happen
after I've gotten the current position. And the function takes
an argument position, which is going to represent
my current position. And it turns out if I want to just
write that data to my HTML document, there's a function
called document.write, much like document.querySelector
took my HTML document and tried to look for
something inside the document. Document.write is just going to
write some text to my HTML page. And I'll go ahead and write
my position.coords.latitude. And I'll add a comma, and then
position.coords.longitude, and just see if I can write that
information to my web page as well. If we go back, and now I'll
go to geolocation.html, what you'll notice is, first, my
browser is prompting me for permission. It's asking to know my location. So that's good. I'll go ahead and allow it in this case. So it took a little while. But after a couple of
seconds, we saw that I now get some coordinates-- some
latitude and longitude values. And if I take those values and
go to Google Maps, for example, and plug in those values
and press Return-- all right. You'll see that I am located
in Cambridge, Massachusetts, and it's able to identify about
where in Cambridge I currently happen to be located. So OK, that's a brief look at
what JavaScript enables us to do. It enables us to look at the structure
of the web page, access parts of it, access the data within it,
and update the DOM-- changing the page that the user actually sees
in response to events, in response to where the user happens to be
located, or whether the user clicked on a button, or what choice they
made from a select drop-down box. And using these features, we
can take advantage of the fact that JavaScript is a full programming
language with things like functions, and loops, and conditions,
and variables to create far more interactive and
engaging pages than what we were able to using just HTML and CSS. This is JavaScript.