CS50 Tracks 2019 - Web - JavaScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
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.
Info
Channel: CS50
Views: 21,608
Rating: 4.9813519 out of 5
Keywords:
Id: 7NPcZSrcA5o
Channel Id: undefined
Length: 47min 46sec (2866 seconds)
Published: Tue Jun 23 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.