字幕列表 影片播放 列印英文字幕 SPEAKER 1: All right, this is CS50, week 10. And you'll recall that last time we introduced one of our additional languages in CS40, that of SQL, Structured Query Language. And this, recall, was a language that we used to query databases, insert data into databases, delete, update, and more, so that we actually have a way of persisting data once we built a web-based application, or really any other application that we want to be able to store data long-term. And we had such statements as create for creating a database or a table, insert, select, update, delete, and a few others as well. And with these relatively few building blocks, we're able to start building a back-end for a web service. And indeed weeks ago when we first implemented a front-end for Google, simply by implementing that web form, we didn't really have anything to do with the data or anywhere to query for data. But now we actually do via our own database in the form of SQLite and via this new language, SQL itself. But today we introduce really the last of our formal languages in CS50. Recall that we began the semester with Scratch, transitioning quickly thereafter to C where we spent a lot of the semester. We have since pivoted to Python of course, whose syntax is quite different, but whose ideas are really fundamentally the same. Today we transition to JavaScript. And JavaScript you'll find is more syntactically similar probably to C than it is to Python itself. So you'll see that a few more parentheses are back, perhaps some semi-colons as well. But what's most important today is that really the fundamentals of programming aren't changing. But rather the method via which we actually execute or run this code. In particular, thus far, when we've written C code, when we've written Python code, all of that code has run on the server, so to speak, within CS50 IDE or maybe on your own Mac or your own PC if you have some prior programming experience. But today we introduce a language that is generally, though not always, used within the client, the browser. Which is to say the code that we start writing today-- and when you generally use JavaScript in order create front-end user interfaces, you will find that the code you write, like HTML or CSS, is actually sent to the user's browser where it's executed, again client-side, on the Mac on the PC. It is not executed server-side. Now to be fair, JavaScript can be and is increasingly used on the server-side as well via frameworks called Node.js, if not others. But we'll focus predominantly on client-side usage thereof. And you'll see that you can start to do some pretty powerful things, because not only now do we have the ability to have a dynamic back-end that serves up data and searches things for us, but a front-end that gives us all the better user interface and features still. So I was thinking back yesterday on when I first started using JavaScript. And it was in a very, very small isolated instance. But way back in the day-- and this is thanks to the wayback machine, you may recall Frosh IMs was something I did in college. Not so much in sports but more the website. And this was essentially the layout-- apologies-- of the Frosh IMs website some years ago. Now this actually post-dates me by a few years, since it seems the codebase actually survived me by quite a few years, surprisingly. But early on, when you would hover over these menu options at top right, those would have what are called event listeners attached to them so that when you hover over some of those menu options, the color would actually change. And I think they shifted positions slightly. So [INAUDIBLE] ultimately took over the site and took it further than that. But this was my first taste of JavaScript. And it was just to give the website a sense of dynamism and to give it a sense of interactivity that wasn't possible, certainly not at the time, with HTML alone. So let's do a quick compare and contrast of JavaScript with things we've seen in the past, just to kind of bring ourselves up to speed on some of the syntax. But you'll find we need to spend relatively little time on the syntax and the language itself, because you'll find syntactically it's so similar. And so instead we'll focus more on ideas and new features of the language itself. So as in C and in Python, we have the ability to express functions in JavaScript. They look a little bit different, at least at first glance. But fundamentally they're really the same. In JavaScript, if we want to function, we're going to use the keyword function to say, hey browser, here comes a function followed by the function's names, zero or more parameters, and then between the curly braces a bit of code that implements that function. So gone is the ability to just indent your code and have the interpreter know what you mean. Those curly braces are back as are more parentheses for us here in JavaScript. But in terms of loops you should find this fairly familiar. In JavaScript if you want to iterate over something again and again and again, the do while construct is actually back. So we have something very similar here as we do in C. And what you use that loop for can be any number of things. But we do have that capability again. Similarly, do we have while or while true loop here, which would induce an infinite loop. And again, these are the kinds of things that might trip you up unnecessarily at first, but quite reasonably. Like if you start capitalizing true again, it's not going to work in JavaScript. So again, reasonable people will disagree when it comes to designing these languages. And so the authors of JavaScript decided to lower case true and false, where again in Python we've been capitalizing recently, true and false. Meanwhile, if you want to declare a loop using a for loop, that is back. But you'll notice perhaps implicit in this example is the fact that JavaScript is, like Python, not strongly typed. It does have the notion of data types. And you can access or look at those data types. But you don't have to specify them as the programmer when you're declaring variables. Rather, in the case like this, when you're declaring a counter like I, which should be an integer from 0 up to 50, you literally say, var, for variable, than the name you want to declare and then just the rest of the syntax is as we've seen before. Meanwhile, there's another handy feature-- and you'll see this in use in various examples perhaps online-- is the very easy ability, like in Python, to iterate over the keys in an object. So recall that an object, at least in Python, is really just a collection of key value pairs. But it's an object can also have methods inside of it. But if we focus entirely on data, keys, and values, this syntax here would allow you to iterate over all of the keys and some value coming back. So maybe if you have a stock object, you could iterate over its name and its price and its symbol, simply by using syntax like this, and an index into the object to get at that object's value. Meanwhile, variables are fairly straightforward. To declare a variable like I, we would say var I equals 0, and a semi-colon. Boolean expressions, meanwhile, are with us still. And these are no different. I is less than 50 might be expressed with this. X is less than y might be expressed with this. So nothing new there. Meanwhile with conditions, we have syntax identical to C. So again, the curly braces are necessary, at least if you have multiple lines that you intend to be associated with the if or the else if or the else. Again we're back to, else space if, instead of L if in Python. But again, there's nothing really new here in terms of content, really just syntax. So after practice and after some trial and error, you'll generally find that it becomes second nature. Meanwhile, we have arrays in JavaScript. So for instance, if we want to declare an array called numbers, again we don't specify the type of this array or the members therein. We simply say var, to give us a variable, number shall be the name of that variable. And then a list here of arbitrary numbers themselves nested in between square brackets. So in JavaScript, as we've seen in Python, we have the ability to express lists or arrays specifically in JavaScript that simply use square bracket notation to define them in a context like this. Meanwhile, speaking of objects a moment ago, we have that same ability in JavaScript to declare them. So for instance, if we wanted to declare an object, and we'll call it quote, we use, as in Python, curly braces. And I say as in Python because in Python really when I say object, focusing entirely on data, I really mean a Python dictionary or dict object, which again is this collection of key value pairs. We don't necessarily do things quite the same way. But in this case here, var quote is a way of porting, say, from a CS50 finance example, a company's name and its price and its symbol. And worth noting here, that as in Python, you actually have choice over the quotes that you use, at least in this context. Single quotes are fine. Double quotes are fine. So long as you are stylistically consistent, it's probably fair to say that many people in the JavaScript community tend to use single quotes here. There's no functional difference as there is in C. However, they do matter, as you'll perhaps eventually see, when you're using not JavaScript per se, but JSON notation. JavaScript Object Notation, which is a simple data format not unlike CSV, but that allows you to store a hierarchical data inside of an object. And the subtlety there is that when you want to store data in this JSON format, you have to quote literally everything with specifically double quotes on the left and on the right. So it's an annoying distinction. And don't fret too much about it now. But just realize any time we're talking about JSON and a technology called AJAX-- more on that soon-- it's got to look like this with the double quotes on both sides of the colon for those key value pairs. Now with that said, let's start to give ourselves some context. Let me introduce a few features that we've kind of sort of seen in Python-- didn't necessarily leverage, but are going to be really integral to the way in which many people use JavaScript within browsers. So here, for instance, is that old simple example of HTML, perhaps the simplest web page that we can write, that quite simply says in its title and its body, hello world. And recall that the indentation here is functionally meaningless. The browser doesn't really care how pretty your HTML looks, just nicer for us humans to see everything nested and nicely indented, because it's just a lot easier to read. And it's also a lot easier to detect if you type something wrong, if something doesn't really line up as you expect. But another way, recall, of viewing this same piece of HTML is in the form of a data structure like a tree, which we discussed way back when in the context of C. And we might draw this same example of HTML with a Dom, document object model, which is a fancy way of saying tree. And that tree might look like this. It's got some special root node that we'll just generically call document, because there might actually be some other stuff like comments or whatever up there. But the root element of a web page, recall, is HTML. The second thing you type is open bracket HTML. The first thing you should type with HTML5 is open bracket doc type HTML. So you can think of the doc type as meaning this node essentially, and the open bracket HTML close bracket meaning this root element. Of course this page here has both a head and a body. That head a title, and that title has a text value inside of it, or a text node so to speak as does the body that happens to be identical. So what's nice about this mental model is that if we tie everything together from weeks past, sort of the markup language of HTML and the data structure of trees and specifically this Dom here, it turns out that you have the ability with JavaScript-- something we didn't have in C really and didn't really have with Python-- but the ability to change this tree in real time. After a browser has downloaded some HTML from a server, typically that content has been static. You can open up Chrome's console in the elements tab and futz with it manually, but those changes aren't persistent, even though you see them. And certainly no user, or no typical user is going to do or know to do that. But you the programmer, if you want a user to be able to download some web page, but then interact with it and have that content change-- very similar in spirit to something like Gmail, whereby every time you get an email, a new row in your inbox appears without the whole page having to reload and certainly without you having to click Reload. Or something like Facebook Messenger, where no matter the time of day if you have Facebook open in a tab, it's just going to pop up a message and keep adding to that little window-- another line, another line, another line of text. So there's this dynamism you get that you can't get from HTML and CSS alone, but you can with JavaScript. If you think of it just intuitively, if you have the ability to run code inside of a user's browser, you could have essentially kind of a while loop that's just constantly waiting. Did the server send me more data? Did the server send me more data? And if so, go ahead with an if condition and write more text to the web page. Write another message in the little Facebook chat message. Write another row to the Gmail inbox. And that's what we're going to get and more with JavaScript. And it turns out, with JavaScript, can we listen for a whole bunch of events so to speak. I eluded to an event, a listener being attached earlier. And this is just a small sample of the events that can be triggered within the confines of a web page. So unlike our Python programming thus far, and unlike our C programming, we have in JavaScript this asynchronicity. Multiple things can kind of sort of happen at the same time or really at unpredictable times because users, of course, are interacting now with our web pages. And who knows when or where a user is going to click. Who knows when he or she is going to click and drag something across the screen or select some menu option or click check some checkbox. So we can't really just write a program top to bottom in JavaScript as we've done in the past per se. Rather, we have to start writing code that says, if I hear a mouse click, or if the user drags their mouse, or if the user checks a checkbox, do something. So kind of like if this then that, if this then that. So a lot of conditions. But it turns out that it's relatively simple to register functions-- that is, associate functions with these various events. And so for instance, when you check a box in Gmail and all of a sudden the row becomes a different color or whatnot, that's because there's an event listener for the click event that Gmail is saying, as soon as the user clicks this event go ahead and change the color or change the interface in some way. Or if you click the little X in the top right-hand corner of a Facebook chat window, the reason it goes away is because there's a click event happening. And Facebook has written code that listens for that click event. And as soon as they hear that event, they close the window and remove it from the web page altogether. So Google Maps, for instance-- drag is an event. So if you've ever kind of wondered, well, how do I click and drag in Google Maps and they just know to show me more of the map, whatever direction I'm clicking in, they're listening for the drag event. And so this is where things get really interesting with GUI side programming-- graphical user interface programming. There's this whole event model, where a bunch of events, a bunch of things can happen at any number of times. Or at any point in time. So let's offer a few general definitions of terms and features of JavaScript. But let's actually discuss them in the context of examples. So JavaScript supports and really, really leverages, typically things called anonymous functions, otherwise known as lambda functions. And these quite simply are functions that have no name. And that seems a little strange. But we will see contexts in which functions don't need names if you're only going to call them once, or if you only need to refer to them really once. So we'll see how to declare and define a function that doesn't actually have a name like foo or bar or whatever. Meanwhile, we're going to see a methodology involving callbacks, which is very similar in spirit to the events I rattled off a moment ago. Whereby a call back is just a function that's supposed to get called when something happens. So in other words, Google and Facebook with those user interfaces, they are registering functions. Really, they're registering callbacks, so that when the user clicks on an X or when the user clicks on a checkbox, or when the user clicks and drags on a map, they have in advanced register a function that gets called back. It's like leaving a message for someone on voicemail. They call you back in response to that voicemail. They call you back in response to the beep that their phone makes when they've received that. So it triggers some kind of functionality, these callbacks. Callbacks are just functions that have been configured to be called at a certain point in time when something happens. Now meanwhile, and lastly, we'll talk about AJAX, which isn't a technology unto itself but a use of various existing features within browsers that allow you to query from a browser, a server to get more data even after the original page has been loaded. Let me go ahead here and create a file called, say, Dom 0 dot HTML. Document object 0 dot HTML just to line up with some of the examples that we'll place online for everyone to play with. I'm going to go ahead and start my page as I usually do. And I'm going to go ahead and say HTML. And then in here I'm going to have a head tag and in here I'm going to have a title tag. And I'm just going to call this Dom 0 for simplicity. Down here I'm going to a body tag. And in here I'm going to have a form. I'm going to give this form, similar in spirit as we did in our discussions of CSS, a unique ID, simply so that I can refer to it as a demo, a demonstration. But let's come back to what more I want to associate with that. First let me go ahead and give it an input, an ID of names so that I can refer specifically to this input field. Let me give it a placeholder of name. And let me say that the type of this field is a text field to close that tag. And then input type equals submit. So a very, very simple web page that looks like this. Now what could go wrong if I present a user with a web page like this? Well, he or she might not give me their name. They might just click submit and this form is going to get submitted to some server. Well that doesn't seem all that great, because I don't have a chance to check, did they actually type in a name? I don't have a chance to do something with it on the client. And indeed that's now the new feature we get with JavaScript. Notice what I can actually do. Let me go into the head of this web page, where thus far we've pretty much only put the title tag. We've put the link tag for CSS. And you may have seen with CS50 Finance that we also had a script tag that referenced a library called Bootstrap, and another one called Jquery. More on those in a bit. But indeed, inside of the head of a web page can go with script tag. And you know what, inside of a script tag can go code, specifically JavaScript. And in here I can define a function, literally. I'm going to call it, greet, just to kind of say what it does. And inside of this function I'm going to do the following-- alert, quote unquote, hello, comma, world, semi-colon. So this is how in this example I've defined a function called greet. I've put it inside script tags, open and closed inside of the head of this web page. Now, nothing's going to happen with that unless I tell the browser to do it on an event. So I'm going to go into my form tag here and say on Submit, go ahead and execute the following code. Go ahead and call the greet method and greet function, and just for good measure return false. But more on that in a moment. So again, my function's defined up top. But nothing happens. Again, when you define a function, nothing automatically happens until you call it. So when am I going to call it? On the form tag here, I have an on submit attribute, which is new today, that says, call the greet function and then return false. But again, more on that in just a moment. So what actually happens here? Let me go into another window, open up DOM 0. And you'll see, if I now zoom in on this form, will see that it's a very simple HTML form with just a name field and a submit box. And if I go ahead now and type in my name, David and click Submit, hello world. So it's not actually saying hello, David, it's just saying hello world. But notice what happened. This is a very bad user interface just using this built-in prompt. But it demonstrates the built into JavaScript are a bunch of functions, one of which is alert. And that function is designed to do exactly this. The window will look a little different if you're using Chrome or Edge or Firefox or Safari or whatever other browser, but you'll see that it simply says, hello world. And it's going to say whatever the URL on your page happens to be. In my case it's just this local IP address for lecture's sake. But this isn't all that interesting to just hard code, hello world, especially when I have the opportunity to take in a user's name. So if I instead go back into my code here, and don't just print out, hello world, but perhaps concatenate with JavaScript's plus operator, the result of this method call, document dot get element by ID, quote unquote name, then dot value. So that's a mouthful. Let's see what this does before we explain what it does. Let me go ahead and reload the page. And now we see the same form again. But this time I'm going to type in David and click Submit. And now it says, hello, David. So how does this work? Somehow or other, I wrote code that not only alerts the user with this window, but it somehow grabs data that he or she has typed in and embeds it in this message. Well here is where we can leverage the DOM, the Document Object Model, and a bunch of functions that come with JavaScript that allow you to programmatically get elements and get data ultimately from a web page. Specifically notice we're doing this. We're calling alert, and then open paren close paren because it's a function call. Quote unquote hello comma, with a space. And again, single quotes, double quotes, doesn't matter so long as I'm consistent here. Plus, which is concatenation, document doc get element by ID, quote unquote name, dot value. So it's kind of a mouthful and it's definitely verbose. And we'll see before long slightly more succinct ways of expressing this. But you can think of document as being this special global variable that's just accessible to JavaScript code that you write. And that really is that uppermost node in our tree, that top-most node in our DOM. And associated with that node, which is just an object, are a bunch of methods or functions, that just come with JavaScript, and that your browser just supports for you. One of those is called get elements by ID. And recall, we've used this jargon before. An element in a web page is the combination of an open tag and a closed tag and everything in between it. So get element by ID quote unquote name means, hey browser, go get me this entire element from start to finish. And this is an empty element because we've closed it within the it's own tag. So that just means, go get me. Kind of a pointer to that node in the tree. There's no pointers in JavaScript. So we should really call this like a reference to this node. But it really just means that. Go get me somehow this node in the tree. And what do I care about once I have that node? I care about its value. So dot value, you can think of like syntax like a struct. That means, if you have this node now, via get element by ID, go inside of it and look for the field with a property called value. And that's going to line up, it turns out, with exactly what the user types. So I can do this again to be clear. Let me go up here and for instance type in Andy and click Submit. And voila, now it says hello, Andy. But now the browser-- and this is perhaps a curse from 10 and 20 years ago when people started to abuse JavaScript and give you hundreds of popovers so to speak, hundreds of prompts if you visit a website that's trying to mess with you. Chrome and other browsers will let you check a box like this, prevent this page from creating additional dialogs, just because it thinks that maybe the page is buggy, maybe it's malicious, and it's really just pestering you as these things are annoying. But at least during CS50 development for P-sets projects, don't check this because it'll only confuse if the page no longer does as you tell it to do. Fortunately that doesn't come up too often on actual websites. All right. So we seem then to have the ability to not only get data from a web page programmatically and display it dynamically. But can we design this code a little better? Well it turns out that we technically don't need to co-mingle our code and our HTML. And notice too there's one other line of code here that's a little sloppy. I mean literally between these double quotes do I have two statements-- greet, which is a function call, and then return false. The reason I had return false is that if I didn't, after clicking Submit and submitting this form, the only thing stopping this form from just being submitted to the server is return false. This says, hey browser, even when the user tries to submit this form, don't. Return false. The default is true. Otherwise, if I didn't have return false and I click Submit, I would see that alert as expected, but the moment I dismiss it, I'm going to be led to some other web page, presumably wherever the form is going to be submitted, which coincidentally happens to be the same page. But now that we're developing client-side applications, client-side web apps, we don't necessarily want forms to be submitted to the server. We want to use them, for now, only within the confines of a browser. Indeed there is no back-end, there is no action attribute for this particular example. But this feels messy. Any time in CS50 when we've introduced some new language like CSS in the context of HTML, or our HTML in the context of Python via our Jinja templates, did we try to factor out one language from another, so as not to blur these worlds and make the code very messy, very unmaintainable. So how can we begin to remove, from these quoted values, code, but still have this feature of listening for a form submission? Well let me go ahead and propose another variant of this program, that I'll go ahead and call DOM 1 dot HTML. I'm going to start with the code from before, but I'm going to make a few changes. Instead of putting it in the head of my web page, for now, I'm actually going to put it down here in the body. More on that soon. But instead of even declaring this as a function, I'm going to instead simply do this. I'm going to get rid of this event handler. So now all that remains up here, to be clear, is just pure HTML. I still have those ID attributes so that I can uniquely identify those forms and that form and those inputs if I want, or that input if I want. But notice what I can do now. Document dot get element by ID quote unquote demo, because that's the name of my form, dot on submit, gets function open paren close paren. And then just for stylistic purposes, let me go ahead and do this, which is what most JavaScript programmers would do. So what am I doing now? Now I have pure HTML appear. But to be fair, I now have a script tag inside of which is code. But at least I've removed the code from like an attribute, which just looked or felt a little sloppy. And look at the code now, document dot get element by ID demo. So this gives me essentially a reference to the entire form, not just that name field. And it turns out that provided that node in the tree is a form, and indeed it is, that has associated with it a property by the definition of HTML5 called on submit. This is a property, that if you assign it the value of a function, that function will get called when the form is submitted. And yet what function do I want to Call Well, function open paren close paren seems to omit a key detail that we've seen in Python and C, which is the name of the function. But here's an example where I don't care what the name of this function is. I don't need to know the name of this function. Because all I need is a function, a chunk of code that will ultimately get executed when this form is submitted. And that line of code is identical to what it was before. So just to be clear, this anonymous function, so to speak that I'm using, is not strictly necessary. If I really wanted to, I could do something like this. I could declare a function called greet, just as before. And I'll format it exactly as I did before. And I could declare this right up here. And then down here I could say, greet. In other words, the on submit handler just wants to know what function to call. So fine. If I find a function call greet, I can tell on submit to call greet. Notice, no parentheses here. I don't want to call the greet function when that line of code is executed. Rather, I want to assign that function, which you can think of as a variable unto itself to this on submit handler. But why? This hasn't really gained me anything. Yes, it's nice that it's called greet. But I'm defining a function called greet only to configure my browser to call that function one line later. The nice thing about anonymous functions is that you can just kind of tighten things up. Why clutter your namespace so to speak? Why fill up your brain with names of functions that you're never again going to need? And so more common and cleaner, better design arguably, would be something like this. All right. And actually just for good measure because this is all part of a statement, in this example let me put that semi-colon there. So the example is going to work exactly the same. Indeed if I go back to my browser and go into DOM 1 dot HTML and type in something like summer and click Submit. Hello, summer. And so it behaves exactly as before. And for good measure, let me go ahead and change the title here to match the name of the file. But now let me go ahead and open up an example I wrote in advance, like many of these, called DOM 2 dot HTML, the code for which admittedly is much more cryptic at first glance. And indeed the syntax will take some getting used to. And you don't strictly need to do things this way. But a super popular library in the world of JavaScript today to this day is something called jQuery. And indeed the bootstrap library with which you're now acquainted by CS50 Finance actually uses, for some of its features, the jQuery library. So let's introduce the syntax so that you've seen it, so that you can use it. But realize, this is not giving us any new functionality. It's just giving us a different syntax. And over time, you'll see that jQuery, like certain other libraries, it tends to make it more pleasurable, more efficient to write JavaScript, because you can do things a little more succinctly. The price you pay is a little bit of complexity. So let's take a look syntactically at this library called jQuery. Notice, in DOM 2 dot HTML, I have this URL up here. There's any number of places to get the jQuery library and libraries more generally. But this one happens to be hosted, for instance, at this URL. And it's the latest version thereof. And this attribute source simply says, hey browser, go get the JavaScript code that I want to have access to from this URL, and assume that it's equivalent to my having written in this web page itself, like our other script tags thus far. Meanwhile, after that, an order is generally important when including things like this. Let me go ahead and do the following. Up here notice that I have this line of code, which generally is a good thing to have because it says the following to the browser. Hey, browser, when the document is ready-- that is, when the whole web page has been loaded, when all the bytes have come back from the server, please go ahead and execute the following code. And we'll see that this allows us to ensure that things don't happen sooner than we actually expect. Specifically, let's do the following. When the document is ready I want the browser to execute the following lines of code that I've highlighted here-- dollar sign, quote unquote, hash demo. It's kind of a mouthful. But this is simply reminiscent perhaps of the CSS syntax that you might be familiar, that simply says, hey browser, go get me the element from the DOM, from the tree representing this page, that has a unique ID of demo. So hashtag demo is just a more succinct way of saying, document dot get element by ID. You can do this all in just a few characters. And the dollar sign here is a feature of jQuery. It's actually just a synonym for jQuery. Dollar signs can actually be variable names. So dollar sign quote unquote hash demo means, hey, browser, execute the equivalent of document dot get element by ID, quote unquote demo. Just more succinct, even though it's a little bit cryptic at first glance. Meanwhile, submit, not to be confused with on submit submit-- submit is a function that per jQuery's documentation says, hey, browser, register the following event handler for the submit event. The way you do this is you provide the library with an anonymous function, which in this case I've just said function. It takes one argument. And I would only know this from having read the documentation. Function takes an argument that we'll call event. But we can call it call it anything we want. And then inside of this code, what do I want to do when the demo form is submitted? Well, I want to use alert. But I want to paste in this value. So again, just new syntax here. And it's fine if you prefer the other syntax for now. Dollar sign quote unquote hash name, means go get the element from the DOM that has a unique ID of name, and go get its value using this method call. So jQuery essentially does this. jQuery wraps existing elements in a DOM. It goes ahead and adds like another bigger rectangle around those smaller rectangles that give you additional features, among which is the ability to use these CSS-style selectors, among whose features is to call like dot val and get the value without having to do dot value, which isn't all that compelling in this case. And then we're appending, in this case, an exclamation point for good measure, just so to show that we can to continue to concatenate beyond one string. And then lastly, is this, which granted, more verbose-- event dot prevent default just means, hey, browser, whatever your default behavior is for handling forms, don't do it. Prevent it, because I want to handle this form submission. So this is a really long way of saying, this is another way to implement exactly the same program that we did earlier, albeit with an added exclamation point, which has nothing to do here with jQuery. So why is this a good thing overall? Well one, your code will actually get shorter over time. But it's fine if you'd rather not use this. But this first line was actually rather important. If I instead were to implement this code like this, there's actually a problem. And actually there's a problem even if I were to do it this way. If I were to go back to DOM 1, and I were to do something like this in this example, and not use jQuery at all, but just, in my head tag, have a script tag that has this code here, there's a problem of the order of operations. On this first line, when I say document dot get element by ID quote unquote demo dot on submit, assign that listener this function, it's too soon. Because the browser at this point in the story literally is reading the file top to bottom, left to right. And the browser has not got to the line of code, where in this form, and its demo ID is actually defined. So this would actually be broken, in so far as the browser's reading it top to bottom, left to right. But it sees this code and it says, hey, browser, go get the element by ID demo. There is no element with that ID at this moment, because it doesn't come until later. So a way of solving this using just JavaScript, is you could do something like the following. Window dot on load get function, and then you could do something like this, albeit fairly verbosely. So that would work. Hey, browser, when the whole window is loaded, then please call this anonymous function. Or we can use jQuery which frankly tends to be more common, at least when using other libraries as well, which says that exact same thing. And in fact, a little bit more than that via this line of code here. So just another way of doing something, another form of syntax. But we won't necessarily assume that or complicate things by using that library syntax along the way. All right. So now that we have the ability to access data inside of my web page, specifically in forms. And I have the ability to alert the user, it would seem we can actually create useful features, not silly little programs that just say hello, world, or hello, David. What if I now started updating past examples to do client-side form validation? In the past, a couple of weeks back, when we did like the Frosh IMs website, or really any website that submits data-- maybe CS50 Finance, if the user doesn't cooperate and doesn't give me a valid symbol or doesn't type his or her name or password or the passwords don't match in the case of registration, the data gets submitted to the server nonetheless and then your Python code thus far has been using an if condition or l if or whatever to check if the user provided the data that you expect. And if not, you apologize to them in some way by just printing out some message to the screen. That's a lot of work. If you can anticipate that something is wrong, why bother sending all of that data or lack thereof to the server, letting the Python code figure out what's wrong and then wait for this response to get back, even though frankly, it happens pretty fast on today's internet, certainly on campus. That's a lot of unnecessary work if you have a programming language like JavaScript that allows you to run code in the browser. Let's open up an example that we did in the past wherein we just have a form that asks for a user's name, their password, their password again, and then has a checkbox by which they can agree to some terms and then a Submit button. And you'll recall that in the past we might have used something like this to have them register. And then we said, no, not really, because we didn't actually have a back-end at that point. But a lot of things can go wrong when we present the user with this many things to do. Now we know from Python, we can catch these things, and we can apologize and display an error message on the screen. So we have all of that program added capability. But what if we could create a better UX, user experience. A lot of websites do fancy things these days like, they don't actually submit the form and then show a big erroneous message with a cat. Instead, they just show the text box into which you were supposed to type a value into in red, or green if you got it right. Or a little alert message saying, you need to give us a longer password, or your name, or your email, or your passwords don't match. But you can do all this instantly on the client side, if we somehow can hook into this HTML. So all of these inputs can be uniquely identified, especially if we go at our own IDs. So let's see if we can't take things up a notch and actually write some code that validates a form like this. I'm going to go ahead and do the following. Inform 1 dot HTML, our next version of this program. We'll start with where I began, with just a simple form. But below this form, just for now so we can get things started, I'm going to go ahead and have a script tag. I'm going to declare a variable called form and call document dot get element by ID quote unquote registration. Why? Well, I'm going to go ahead up here and add an ID that equals registration. And again, here I'm using double quotes in HTML, even though both single quotes or double quotes are allowed. Down here I'm using single quotes, mostly just to be conformant with convention. But you can certainly stylistically do whatever you want with both of these. Now I'm going to do form, which is just an HTML form, and say on submit, get function. So in other words, hey, browser, when this form is submitted, call this anonymous function. But again, the fact that the function is anonymous really is not an interesting detail. It just means it has no name. This is the chunk of code that will be called when this form is submitted. All right. What do I want to do? How about this. If form, its e-mail field has a value that equals equals quote unquote, that's a problem. Let me go ahead and just alert the user, missing email. And because we don't indeed want the form to be submitted, let me go ahead and return false. Else if, form dot password equals equals nothing-- the so-called empty string-- then let me go ahead and alert the user that we're missing their password. And then let we return false so that the form does not go through because it's not ready to go through. How about else if form dot password dot value. Oops, and up here I need value as well. Otherwise you get the element from the DOM, you don't get the value inside of that rectangle. Else if form dot password dot value does not equal form dot confirmation dot value. And why confirmation? Well, if I look back at my HTML, the first field was called e-mail. The second field was called password. The third was called confirmation, even though it's also a password field, because that's where I want the user's password again. But if those passwords don't match, let me tell the user, passwords don't match semi-colon return false. Now wait a minute, my color-- my syntax highlighting is all messed up. Why? So this is a common gotcha. If I just want to use English grammar in this case, don't is the right spelling there. But because I have quotes just like in C or in Python when you've used double quotes inside of double quotes, you're going to confuse the program in this case. And so I need to escape this. But as in other languages, escaping a back quote here is as simple as this. Or if you don't really like that because it just looks a little ridiculous and a little harder to read, we could switch to double quotes here. But again, just because I'm using single quotes everywhere else, I'm going to stick with single quotes and escape it. But again, you could make an argument either way. Ouch. There's still that checkbox. And that checkbox, let's see, was called agreement. So it turns out in JavaScript you can express that as follows. Else if it is not the case that the form's agreement checkbox is checked. So it turns out, associated with checkboxes in JavaScript is a property called checked that's going to be true or false. So if that's not checked, I'm just going to tell the user as much. Checkbox unchecked, and then return false. Otherwise, if none of these checks fail, and I get all the way through all of these if's and else if's and nothing seems to be wrong, you know what, the form is ready for submission, return true. And so now it actually makes a little more sense perhaps, to return false or return true, because in all of these erroneous cases you want to return false. But if everything's OK, by default, we're just going to return true. And the browser's default behavior in that case is going to be to go ahead and submit the form to the server. So let's try that. Let's go into form 1 dot HTML. Notice that if I zoom up here, we have more fields than before. E-mail, password, password, again I agree in register. So let's try this. Let me go ahead and say, no, I'm not going to give you any of this information. So let me click Register. Missing email. All right, fine. I'll cooperate and give you at least my e-mail, mail in at Harvard dot edu. Let me click register now-- missing password. Now there's the additional checkbox there because now Chrome, or your browser more generally thinks that, maybe this website's buggy or it's being malicious or annoying at best. Let me not check that box, otherwise none of the rest of the demo will work. All right. I'll give you a password. Register. Passwords don't match, that's because I didn't type it again. So let me type the same password again over here. Nice. Ah, checkbox unchecked. All right. Agree, register. Ah, and it even wants to save my password, but not really. So where did this actually go? Well just to show you what's going on behind the scenes, notice that the action attribute of the past couple of forms have been slash register. Well it turns out with today's examples, I'm actually currently running Flask. And inside of there I have a couple of routes. We're going to use one of those in just a bit. For now I'm just using this one here. I have a route for slash register, that calls a function register that simply renders a template called register dot HTML. So where did that text come from? Again, this is just stuff from a couple of weeks back. If I go into registered dot HTML in my template's directory, it's just that. You are registered. Well not really. So we're not focusing on the back-end. We're not focusing on Python. We're not focusing on Flask. But I do have it running right now, so that we can see what does happen if the form is submitted. But that could be any server in the world. It could even be Google if we're building that search engine again. I just need something running there. Let me go ahead and show you just an alternative take on this form, version two, that does things using jQuery. Again we won't dwell as much on this. But do get familiar with the syntax, because you'll see it everywhere online. This says, hey, browser, when the document is ready, go ahead and associate this anonymous function with the submit handler of the form with this unique ID. And then here a slightly different syntax by which you can select fields on the web page. Let me wave my hands at that for now. Because again, you can go with the DOM-specific functions we've been using thus far. Or when the time comes, just read a little more closely some of this code here. But this is the equivalent code in jQuery, which is just a library that just gives you different ways of expressing things in JavaScript. But this form is pretty ugly, right? Like, this is really not something to write home about. This also does not suggest the best error handling if every time I do something wrong I just get this ugly looking alert. Can I make something prettier? Well we certainly could with JavaScript alone. And I could certainly write some HTML, some CSS, and a whole bunch of JavaScript myself and get a much better UX, user experience. I could get a much better aesthetic to the site, so that maybe we print some red text or green text, depending on whether the user is cooperating. But that's a whole lot of work. And honestly, there are millions of websites out there these days. Surely someone else has had to validate a form before, and he or she has done it with JavaScript, and he or she has been nice enough to make their code freely available as open source online so that the rest of us making the other millions of websites can stand on their shoulders and not reinvent that wheel. And indeed, just like in Python, there's lots and lots of libraries, and lots and lots of frameworks, so in JavaScript it's there the same. So it turns out, if I go into form 3 dot HTML, I have a slightly prettier version that is using the bootstrap library. There's no banner or menu or anything like. I kept it pretty simple here. But just by adding a little bit of more HTML markup, and a little more CSS, can I stylize my form to be much prettier. Indeed in CS50 Finance we had much nicer forms than the previous few examples because we used Bootstrap, though you could use most any other library that's out there as well just to make the forms a little prettier. But I'm adding one additional library. This one that supports Bootstrap, so that if the user doesn't cooperate with this version three, notice they can't even click Register without the following happening. Red email, please fill out this field. Red password, please fill out this field. And by the way, not long enough, because it's not even any characters. Password again, please fill out this field. Checkbox unchecked. So you can immediately give much prettier output to the user without using that sort of a lame prompt that's just going to pester the user again and again. And even though there's still an opportunity, I think, to improve the aesthetics, this is much more akin to web 2.0. So modern websites that are using these and other libraries to just create better user experiences. So let's cooperate now. M-A-L-A-N. And notice, whoops. That's not even my email address. The error message now goes away entirely because the field is not blank. All right password, 1, 2, 3, 4, 5. OK. It's now no longer telling me to please fill it out, but it's still not long enough. All right. 1, 2, 3, 4, 5, 6, 7, 8. Eight characters seems to be enough. All right. Let me go ahead and type in foo bar baz. Passwords don't match. OK. 1, 2, 3, 4, 5, 6, 7, 8. That one now matches. And finally, I agree. So we get so much functionality for free. We could implement all of that ourselves using just the primitives we've looked at thus far, just our understanding of where JavaScript has to go in the web page, just our understanding of how to write functions and if conditions and for loops and while loops or whatever. But it's not interesting work. If I'm trying to build a finance website or a final project more generally, I don't really want to focus on form validation. I want to focus on my own intellectual property, my own ideas, my own project itself. And so in form 3 dot HTML is a few additional things. Not only have I included the Bootstrap library at the top, as you might have noticed in CS50 Finance, as well as the latest version of jQuery, and Bootstrap's own JavaScript, I've also included-- and I found this just by Googling around. A very nice person made his or her code available at this URL. And there's documentation online. And he or she based it on Bootstrap so that if you want to use Bootstrap and have pretty error messages, that you don't want to think about creating yourself. You can use their library. And indeed, notice how I changed my HTML. It's a little more verbose to be fair, but you'll remember some of this from maybe your log-in form or registration form from CS50 Finance. Most of this just comes from Bootstrap and you're using the classes that they tell you to. But there's a few fields here that control how this new library is working for form validation. Notice, on my input, not only do I have a Bootstrap class, which I just read from the documentation and in the unique ID, I've got a required attribute. And by saying required, that's a clue, not only to the browser, but also to this library specifically that I should not be allowed to submit this form until this field is filled out. Now notice down here, input class equals form control, which is just a Bootstrap thing. Data dash min length equals 8. This is how that library knows that I, the programmer of this page, wanted the user to type in a password that's at least eight characters long. It turns out, in HTML5, you can prefix, or rather you can invent your own attributes. Any attribute that starts with data dash, and then some other sequence of characters can be your own custom attribute that does not come with HTML itself. So a lot of libraries, this one among them, use those data attributes in order to configure themselves. In this case, it's configuring itself to use a minimum length of eight. That's also required. Down here it's a little more advanced. But I just figured this out by reading the documentation. Down here, notice, I've got that confirmation text box that's also an input with a Bootstrap class data dash match equals hashtag password. So this is-- and you'd only know this from the documentation of the library-- this is how the author decided to let us configure this text field in such a way that it must match this password field. And you know what, data match error-- I would only know this too from its documentation. But the way the author designed his or her library is if there is an error and the passwords don't match, this is the read text that I want the library to display on the screen. And though it's cut off, this field too is required. And meanwhile the checkbox, if we scroll to the last feature here, that too has been prescribed as required. And notice, I've also added some divs here and there, help block with errors. This is not some fundamental HTML thing. This is, again, just the author of the library who's decided that wherever you, the programmer, put a div with these classes, the library will plop those read error messages. So they don't have to be right there. You could centralize them at the top of the screen. You could put them in a banner at the bottom or wherever you want. You have some programmatic control. And so this library is implemented in JavaScript, though we haven't written any additional JavaScript code because this author has been pretty clever and is using special HTML attributes to configure his or her library. And it suffices, at the top of the page, simply to include that library. And it has been written, probably with a line of code like document on ready. Like when the document is ready, search the HTML for those special tags and make sure that this form shall be validated accordingly. So this is what's really exciting about JavaScript and Python as well, and any of these higher level languages is just how many features you get access to for free, without having to implement them yourselves. How you use them is going to totally differ. And indeed, part of the process of making a final project or a web application or a mobile application in general, is using a fundamental understanding of programming and loops and conditions and functions and so forth, but then googling around and looking up documentation that empowers you to do other things with that understanding, using other people's code. So again, the goal is not to absorb all of this en masse, but rather to realize the fundamentals, the ingredients by which we can configure and do things ourselves. Let me go ahead and propose now this example. So back in my day, when I first learned HTML, for better or for worse, mostly for worse, there was a blink tag. So someone back in the '90s thought this was a good idea. Let's empower people to have blinking text on their screen for everyone to see. There was even worse, perhaps, or as bad, like a marquee, where you could scroll text across the screen from left to right or right to left-- I forget which direction-- and that too felt like a good idea at the time that has since been removed as well. But it invites an opportunity, I dare say, to reimplement this feature, even though browsers do not support the blink tag now. But I can figure out how to do this. Right. What's going on? There's some big text on the screen, that's roughly centered. So I can probably use some CSS for that to make it big and bold and centered. It's blinking on and off. Well what does it mean to blink on and off? Again, reduce this to first principles. What capabilities does a browser have? Clearly to display text, also to display colors, we have seen. So maybe the act of blinking, hello, world, is really just a matter of hiding it, showing it, hiding it, showing it. Maybe there's a way to do that. And indeed there is in CSS. Or maybe it's still there, it's just going black to white to black to white to black to white. So it feels like, so long as I have the ability to kind of sit-in a loop, maybe even an infinite loop if this just keeps going, and every second or so, every half second go ahead and change from black to white, to black to white, or hide show, hide show. I just need to kind of commingle these capabilities of JavaScript and CSS. And right now I can't stare at this anymore. So let's go ahead and open up blink dot HTML and see how I implemented this. So here's a body tag. Here's a div tag that has unique ID greeting. And then, hello, world as my text. So the HTML to this page is super simple. If I scroll just a little bit, this is why that text is now centered and big. So 96-point, I decided, pretty arbitrarily, just to make big centered text on the screen. What about the JavaScript code? It turns out with JavaScript, just as you can gain access to data in the page, so can you gain access to CSS in the page. And in fact, even though we won't dive in underneath the hood of that library for Bootstrap that made our text fields read, how did it make our text fields read? Well, if we really looked underneath the hood, that library, upon seeing that you didn't type your name or your passwords don't match, it changed underneath the hood the CSS of my web page to go from default colors to red or to green or to whatever. But how did it do that? Well, it turns out that browsers have the following capability-- one, to declare functions. And we know that already. Two, to get elements by their ID. And we know that already. And here I'm just declaring a variable called divs, so my code's a little more succinct. But it turns out that elements on a web page, certainly divs, which are just big rectangular divisions of the page, have a style property associated with them. And a style property, in this case, lines up with that div element, CSS properties, if any. And if I want to change the visibility of this div style, and visibility happens to be a CSS property that we haven't necessarily used, but if you googled around you'd see an online reference of available CSS properties. If the visibility of this element equals equals hidden, I'm going to make it visible. Else, I'm going to make it hidden. So if visibility is hidden, make it visible. Else, if the visibility is visible, make it hidden. For whatever reason, the opposite of visible in CSS is not invisible. It is hidden, which makes this a bit of a mouthful. But this if block here, this if else, really is just saying, if visible, make it hidden. If hidden, make it visible. So just toggles the state, so to speak, from one to the other. But why would this function operate more than once? There's no loop. There's no for loop, no while loop, no do while loop, nothing. Look at this last line of code. It turns out that in JavaScript you have the ability to do things again and again with a clock that's running inside of your computer, essentially. Window dot set interval is a function you can call in JavaScript that says, hey, browser, call this function every 500 milliseconds. So couldn't quite glean it before visually. Every half a second, call this function, call this function, call this function. And notice again, as before, when I'm passing around a function by its name, I don't want to do this. If I said, blink open paren close paren, that would call the blink function, and it's only going to call it once. I instead want to pass this function by its name. In C we would call this a function pointer. In JavaScript we call it by reference, passing in the name of this function to set interval. So that set interval knows later what function essentially to append parentheses to, so as to call it every 500 milliseconds. Now how that's implemented, I don't know. I don't care. It's abstracted away from me. But set interval is a function that comes with the browser that probably has some kind of infinite loop that knows to check every 500 milliseconds what's going on underneath the hood. So this is to say, in JavaScript, we have the ability to control CSS. And indeed, if we now think back retrospectively, that must be how that bootstrap library was doing the form validation and making my fields red when I did something wrong. So you have another feature in JavaScript called local storage. This is relatively newer, but it's a way, on a website, of storing information for the long term, in a user's browser. So in CS50 Finance, and in Web Programming with Flask more generally, we had the ability to store data in sessions. And that's fine. But sometimes it'd be nice to store data locally inside of the user's browser so that you don't have to remember states on the server side. So that you don't have to contact the server to get that information. And so this is particularly common in web applications that you kind of want to be able to run offline. Right. It's increasingly convenient, especially on mobile devices, to be able to run those web pages when you're not connected to the internet, when you're underground or on a plane, so long as you loaded the page in advance. So with local storage, you actually have exactly that feature in HTML to store information locally. So let's take a look at this page does and then we can deconstruct how it's doing that. If I open up storage dot HTML, notice that it says in the top corner-- and I'll zoom in, just the number 0. If I reload, and reload, and reload-- and to be clear, all I'm doing is reloading by using my keyboard-- and reload, and reload, and reload, the counter is going up. But why is that happening? Well, let me go back into the IDE and focus on these lines of code here. If it's not the case that there is an item called counter in this special global variable called local storage, then you know what, set an item called counter equal to zero. So local storage is really just a JavaScript dictionary-- an object that's accessible globally to you. Now we've not seen this before, and it's not all that common to need, but I did it just so I could display something dynamically in the web page. You can call it document dot right, which is similar in spirit to prints in Python or print F in C. But, again, we don't really print to the screen as much as we change values or HTML as we've done in the past. So we won't really use this too often. But for now, I just want to write local storage dot get items return value when I ask it for counter. But then, and this is the key detail. Every time I print or write that value to the screen, I want to go ahead and reset the item, called counter, to the result of calling parse ent on local storage dot get item dot counter plus 1. So long story short, local storage is going to store key value pairs for you, but as strings. And that's fine, because like quote unquote one, quote unquote two is still useful, but parseInt is a function built into JavaScript that's going to allow me to parse this string that I get back and convert quote unquote something to an actual integer so that I can then add 1 to it and set it back. So this example is only to say, there is an ability to store data locally in the browser. And this is a fundamental alternative, especially for offline mobile apps, to storing data in sessions on the server side. But things get much cooler, quickly. In fact, let me go into geolocation dot HTML, which creepily wants to know my location. Not my location in the sense of the IP address. I'm seeing the IP address of my computer here. You'll see something with CS50 dot IO or the like most likely. But this is standard prompt that Chrome and Edge and other browsers will trigger if a browser is running JavaScript code that is creepily trying to get your GPS coordinates. So it's a good thing that there's privacy defenses in place. And you really see this on Android and iOS, which don't let apps do anything without your permission typically. But I'm going to go ahead and let it know my location. I'm going to go ahead and click Allow, and see what happens. It's taking a moment. The computer is thinking. I am apparently at GPS coordinate 42.38 comma negative 77.11. So that's my latitude and my longitude. Now that's not all that interesting unto itself, but let me go to something like maps.google.com. Turns out you can search by latitude and longitude. OK. We didn't have to go very far to triangulate my position there. There we are, roughly in the middle of the building, Sanders Theater here in Cambridge. So that's kind of cool. This is all to say that a browser can apparently infer your location. Now why is that useful? Well if you're building a website that is designed to show maps to the user like Google Maps or MapQuest or Yahoo Maps or Bing Maps or any number of tools, it's kind of a nice feature to just let the user see where he or she is in the world by default, rather than just showing them the generic United States or the whole globe. It'd be kind of nice to at least show them the general area. And indeed, that's exactly what happened when I went to Maps.Google.com. It knew, within some range, where I was already, even before I typed this in. If you're implementing Yelp or some restaurant review site or something like that where you want to be able to find something near you, it's nice to not have to have me, the human, type in my GPS coordinates, which I certainly would never know. And it's nice to not make me type in Cambridge, Massachusetts or New Haven, Connecticut or whatnot, which is in 06511. Rather just let the browser actually figure out where I am, so long as I consent to actually doing that. I did get that right this time, right? OK. So why is this a useful thing? So this, of course, is useless. Like, who cares what GPS coordinates I'm at? Not all that useful unless you want to target me right now in a map. Rather, we can do something more interesting. So we need the ability to actually get a map. Thus far I have no ability to pull down pictures of maps. But what if I could make a website, that after downloading some HTML and CSS and JavaScript, what if, ala Google Maps, I could go get maps of Cambridge, go get maps of New Haven or wherever I am in the world and display them to the user. And better yet, what if I could then use the drag event and actually get more of that map-- whatever's off the screens above, to the left, to the right, or below me, when that user clicks and drags. Drag being one of the events we can listen for. Well it turns out, as mentioned earlier, that browsers today support AJAX, which is formally called asynchronous JavaScript in XML. But people don't really use XML for this anymore. They use JSON, JavaScript Object Notation. And this is ultimately referring to the ability of modern browsers today, upon already having downloaded a web page and CSS and JavaScript, to make additional HTTP requests from browser to server, without having to reload the whole page, and certainly without the user having to click Reload and then see a big blank screen for a moment, after which they see content. It can all happen dynamically. So Facebook Messenger, Google Maps, Google Gmail and so forth-- any number of websites you use today, certainly the most modern of them, all use this capability. So how do we go about using it? Let me go ahead and open up a file called AJAX 0 dot HTML. And here is now where honestly you want to use something like jQuery. It tends to still be super popular. There's other libraries that can do this for you. But what you don't really want to do is start writing native browser code, so to speak, that's specific to Chrome or specific to Edge or specific to any number of browsers. One of the nicest features about libraries today is that there are so many stupid cross-browser incompatibilities whereby reasonable smart people can disagree, and so different companies have implemented browsers ever so differently in terms of JavaScript, in terms of HTML, in terms of CSS. So literally, you might build a beautiful looking website. Spend hours and hours getting it to look perfect on your Google Chrome browser, and you open it up in Internet Explorer or Edge or Firefox or Safari, and damn it, it doesn't look right. Something's off aesthetically. It doesn't even work maybe. It doesn't even load. And so a lot of the process of getting websites just right is certainly building them in the first place, but then that last stretch is really about making sure in testing that things work on multiple browsers. So this is all to say, this is when it gets really useful to use something like jQuery, because stuff like AJAX does get relatively simpler as follows. Here is a web page that's including the jQuery library up top. Inside of my own script tag now is a commented function called quote, similar in spirit to what we might have wanted in CS50 Finance if we were using JavaScript at that point. Notice what I'm doing in JavaScript though. Give me a variable called URL. Set it equal to quote unquote slash quote, which looks like a route, question mark symbol equals, closed quote, plus which is concatenation, the value of the symbol field. Now what is this? Let me fast forward to the HTML down here in AJAX 0. Pretty simple web form and I'm doing it old school here. Form on submit, call the quote function return false. And then have an input whose ID is symbol of type-- and it's a little cut off-- is text. So what does this page look like? If I go over to AJAX 0, and open this here, it's a very simple web page that simply has a text field with a placeholder that says symbol, and then an HTML submit button that says get quote. But I want this site to do is the following. If I type in GOOG for Google's stock ticker symbol, I want to know right now that it's worth $772.02. If I type in something like Microsoft, that's $59.705. So I'm getting another digit of precision from Yahoo Finance as it turns out, as we'll see. Netflix, get quote, $123.3405. So in this case we're really getting some additional precision. But all of that is immaterial at the moment. What I really just care about is how this is working. So again, when that form is submitted, the quote function is called. And then it returns false. And that's just so that it doesn't get submitted to a back-end, because there is no back-end at the moment. Rather, I'm using JavaScript to talk to my back-end as follows. Var URL gets this URL equals this value. And this value is whatever the user just typed in. Me, like Google or Microsoft or Netflix. So this a way, notice, of constructing your own path for an HTTP get request. If you think back to week six, we know that you can contact websites ultimately via this route, like slash quote. The question mark is what separates the route from the HTTP query, or the request parameters, the HTTP parameters that you're passing in, one of which I've decided to call symbol. And now notice what the jQuery library does for us, pretty straightforwardly. jQuery comes with a method called get JSON. Now what is this weird syntax? Again, this is just JavaScript being cool, or jQuery being cool. The dollar sign is literally a synonym for an object called jQuery, a global object that happens to exist because of this line of code. But the author of jQuery, some time ago realized, dollar sign is actually a valid character for a variable name, which is not the case in C. So you know what, I am just going to call my library's global object dollar sign. Why? Well one, it kind of looks cool, but two, it's just much shorter to type. You don't have to actually write out the whole word. But that's all. There's nothing syntactically interesting about this. It's just valid variable symbol. Get JSON does that. It contacts a server at a certain URL and expects to get back a JSON object, which we saw an example of a bit ago. And what does it do? It will call a function, in this case anonymous, but that's an immaterial detail at this point. And it will pass to that function a reference to the data it gets back from the server. So again, get JSON somehow figures out underneath the hood, how to make an HTTP request to that URL that's passed in as the first argument. And when the server finally replies, this anonymous function is called. It's passed that data. And then we call alert on data dot price. So what is inside of that object? Well I can actually simulate this. Right. If you understand HTTP, you can do all of this yourself. My IP address happens to be on my local machine, 127.0.0.1. And then I'm on port 80. Your URL might be different, on CS50 IDE. But what I do know is I can construct my own HTTP request by just doing slash quote question mark symbol equals NFLX and Enter. And notice what comes back. If I zoom in on that, this is JSON, JavaScript Object Notation. Why does it look like this? Well, the world just decided, we need a way of standardizing how you get back data. It's useful to get back data in terms of metadata keys, and the actual values you care about. So the world decided that JSON data is going to start with a curly brace, end with a curly brace. It's going to have a whole bunch of key value pairs, which are separated by colons. Each of the values, each of the keys rather, is quoted. Each of the values is quoted if there are strings. Otherwise if it's a number you can just write it like that. Commas are separating each of those key value pairs. And again, you must use double quotes in this context, which is a long way of saying, this is what my slash quote route returns. This is not a web page. This is not my quote route from CS50 Finance, which was must prettier and it actually had CSS and HTML and it said, a share of Netflix costs such and such. This is just raw data. And this is where AJAX gets compelling. AJAX is the use of raw data like that, you have programmatically requested from browser to server, after the original web page is already loaded, because you want to get more data for the user, perhaps in response, as in this case, to his or her input, like when I typed in Netflix or Google or Microsoft. This web page isn't all that pretty though, of course. Right. It's ending up just using that alert. And it probably is the case that we can do things a little bit better. And indeed we can. Right now, again, I've kind of regressed. I should not slip into this habit. It's fine for perhaps a lecture demonstration, but let's clean this up right now. If I go into AJAX 1 dot HTML, notice I've gone in and cleaned up my HTML. No longer do I have some hackish call to a function semi-colon return false inside of the value of an HTML attribute. It's just bad design to do that. It's fine to sort of get warmed up. But let's get rid of that, clean up my HTML, and now relegate everything to the top of a file. I'm still using jQuery, but I need one additional line, recall. Now I need this line here. Because a browser reads my code top to bottom, I want to make sure that this code is not executed until the page is ready. Before, I didn't need to worry about this, because by the time the browser got to my HTML, saw the on click or on submit attribute, rather, and saw the code to execute, that's fine because everything else had already been loaded. But in this case, I have my code up front before the HTML. So I have to say, hey, browser, don't do this, until you're actually ready. What do I want you to do? I want you to, as before, register a submit handler, calling in this function, calling get JSON as before, and then return false here. As an aside, let me point out just one thing. It turns out that putting your JavaScript code in your file, that too is not generally good design. Certainly as your pages get more involved and your code gets more complex, just like in CSS when we factored out our CSS, we should be able to factor out our JavaScript code too. So actually a better practice longer term and certainly with projects would be to do something like this. To take all of this code that I've written, save it in a file called whatever, scripts dot js is perhaps common. And then in my HTML page, don't just have this big open tag and closed tag. Instead, go ahead and say something like this, scripts dot js. In other words, have a URL or partial URL that says to my browser, hey, browser, besides the page you're currently reading, go get this file as well. Execute any code in there and then proceed to run whatever's inside. All right. But-- but, but, but, I bet we can make this even cooler. It is pretty, pretty lame to keep using these alerts. What if instead we had this capability as well. In AJAX 2 we have this example here. Let me go ahead and zoom in. And let me go ahead and type in NFLX for Netflix and click get quote. I don't want that damn alert anymore, which is pretty hackish. And again, it's going to look ugly and different on different browsers. Let me click, get quote. Woo, hoo, hoo. Very nice. So this time it seems to have embedded the response in the web page itself. And that's going to change GOOG, get quotes, aka Alphabet, or Microsoft, or whatever other company. Somehow we're changing the page. In other words, now we're not just using this out of band alert function. We are changing our DOM. And in fact, let me do this. Let me reload the page to get back to original state. Let me control or right click on Chrome and go into Elements. As you may know here, notice that here in my web page, apparently is a paragraph that we can't see, because it's got no text inside of it. It's just an open tag and a closed tag. But notice the unique ID called quote. And notice what happens. I'll have to zoom out to see this. But notice what happens. If I type in like GOOG and click, get quote. Don't watch the top. Watch the bottom. A triangle appeared, because now there's something inside of that. So that sentence was dynamically inserted. Let's try this again. Let me try with Microsoft click, get quote, and my page's HTML is changing. And it's also flashing it in purple just so Chrome can draw your attention to it. How about Netflix, get quote. So this is where we're really now tying everything together. We have the ability with JavaScript to get values from this field. We have the ability with JavaScript via AJAX, which is just a use of JavaScript to get more data from the server. We have the ability with JavaScript to change my DOM, my web page, which really just means change the HTML in that page, not permanently. None of this is happening on the server, these changes here. It's just in my own local browser. And indeed if I reload, the changes go away. But if you think of this sentence here as being like another row in your Gmail inbox, or another message in your Facebook chat window, that's all that's happening. Now I might be just clobbering, that is deleting and changing the previous sentence. But there's nothing stopping me from just writing every individual message to the screen again and again and again. I don't have to overwrite it as I'm doing here. So how do we do this? So if I go ahead and open up now, AJAX 2 dot HTML, it's almost entirely the same as before, except I am now embedding inside of my DOM via these method calls, the actual data I want the user to see. Indeed, this is saying, hey, browser, go get the HTML element whose unique idea is quote. Call a method associated with that, called HTML, which we haven't seen before. But it just literally changes the HTML of that element to be whatever I pass in as an argument. It's a long argument, but that's just the concatenation of a bunch of strings-- A share of, plus data dot name, costs, dollar sign data dot price, period. Now, what is data dot name? What is data dot price? Well data is just the argument to the callback function, which was, again, the anonymous function that I passed in the second argument to get JSON. Data dot name gives me the name therein. Data dot price gives me the price therein. If I really wanted the symbol again, I could do data dot symbol, based on what we've seen inside of that object. But, just like in C, structures, we just use the dot operator in JavaScript to get at the properties of the data inside of an object. Now again, the only way I would know how to do this with jQuery specifically is by looking up its documentation. And I would know that if I want to get JSON I called dollar sign dot get JSON. I give it a URL, which I've constructed here. And it can be just the relative path if I'm assuming that page is on the same server, that route's on the same server. And then the second argument should be a function. It can be anonymous, doesn't have to be anonymous, doesn't matter so long as that function, per jQuery's documentation takes at least this one argument, which I could called data. I could call it anything else. But the documentation for jQuery says, hey, user, I will pass to this function that I will call back as soon as I have some data for you, whatever the server gives me. And the server has given me a name, a symbol, and a price all inside of this object, this JavaScript Object Notation. Finally, this last line is just kind of nice to have. I realize, you know what, it'd be a nice feature if after the user searches for a stock quote that we not only see it but we also reset the form to be a blank value. So notice that this symbol refers to a unique element, the unique ID of an element that's not a paragraph tag, as this one is. This is an input field. And input fields don't have HTML inside. They literally just have textual values. So I use dot val instead, passing it in an empty string. But the net effects, notice, this time with that line is the following. Once I've added that line, I have, GOOG, get quote. And notice the field clears itself this time. Once I have Yahoo here, get quote, it clears itself this time. So by adding that kind of line to this example, which just happens to be using a bit more jQuery, I now have the ability to reset the field as well. All right. Now where was that JSON coming from though? Well recall in application dot pie, we had a couple of routes, one of which was register, which was not all that interesting. It just rendered a template called registered dot HTML. But the other route, which we only glanced at a moment ago, was slash quote. This one's a bit more involved. And I've actually omitted some error checking to keep the code a little tight. You'll see more error checking and more code inside of helpers dot pie from CS50 Finance. But long story short, these five rows of code simply contact Yahoo Finance, passing in that symbol that's been provided, get back the response in CSV, convert the CSV to JSON, and return that JSON. And so this is the code that responds to get requests of the slash quote route, which is what my JavaScript code is using. So again to be clear, we don't have new capabilities necessarily with rendering this financial information that we didn't already have with Python. What has changed is, now I am doing that HTTP request, and I am changing that web page client-side. I'm contacting the server, yes, but only for additional data, only to get that JSON data, only to get the name, the symbol again, and the price. I am not asking the server, hey, server, could you also give me a brand new web page with HTML tags and a body tag and a head tag and a title tag and all that. I'm not asking the server for a whole darn new page as Jinja might have given me by using a template in, say, CS50 Finance. All I'm asking the server for, is please just give me a stock quote, and I'll take it from there. And so now we have, frankly, a much more responsive interface, because I'm requesting less data of the server. That's going to be a smaller number of bytes, which means it's quicker to send it back to me. And I already know how to display it so there's just a lot less work to do. So in this case, it would seem that the introduction of JavaScript hasn't changed what I can do, but certainly has changed how I can do it. But it's easy to be misled. In our previous examples, when we did some form validation, recall that we could similarly validate that the user typed in the right thing or the wrong thing, client-side, without talking to the server. And the result was prettier for sure. We had a little red text and so forth. Though technically we could do that server-side as well. It's just easier to do it client-side. But it was faster. I mean, we don't really notice on the wonderful internet speeds we might have right here on campus. But certainly on mobile devices, if I took out my own phone, it's going to feel slower, certainly if you're on a slower connection it will certainly be slower. But it's not sufficient to just get rid of the server altogether and only do client-side. In fact, it turns out, an adversary, whether maliciously or just accidentally, could do something like this. Recall that this form here asked for my email, password, password again, and an agreement. And if I don't cooperate, it yells at me-- missing email, missing password, passwords don't match, checkbox unchecked, or whatever. But it turns out that hacking JavaScript, turning it off, is as simple in Chrome or any other browser, poking around your settings, as I'm doing here, scrolling down to an option called, in this case, disable JavaScript. And now after simply disabling JavaScript, woo. I am registered. Well, not really. But I am not registered. I did not give an email address. I did not give a password. I definitely didn't give it the same password again. And I certainly didn't agree to those terms and conditions. So JavaScript is really just a client-side nicety. It gives us amazing new features. It gives us amazing responsiveness. It is not an alternative to security checks, to validation of data on the server. All of those lines of code from CS50 Finance, all of the lines of code you might have on the server in Python or whatever language that are validating user submissions to make sure they're cooperating, apologizing or admonishing them accordingly, if they don't cooperate are still necessary. So it's a little annoying that in order to benefit from this client-side responsiveness, this better user experience, you have to now pretty much invent the wheel in two places. In the client-side in JavaScript, on the server in Python or whatever language. But that's the way it is. If you want to achieve the best of both worlds. The security that you get by actually doing something as close to your database as possible on the server, and the nicety that you get, the user experience that you get, and the immediacy of responding to the user by using JavaScript alone. So it turns out, there are some libraries that allow you to, on the server, specify what fields are valid. And you can let the library on the server generate the requisite JavaScript code with which to validate your form. So long story short, thankfully, other people have helped us solve this as well so that you only do need to write the code once if using the right library. But it's the principle that's important. In fact, too often on poorly written websites, is it possible to circumvent some silly checkbox or some requirements that's not really a requirement. It's really just a JavaScript imposed request for data, if they're not actually validating as much on the server. So realize that that need on the server remains. All right. Back to that map. We have the ability, recall, to get the GPS coordinates of where someone is. We have the ability, with AJAX, to get more data from the server. And though the data we've gotten this far has been stock data, there's nothing stopping us from getting images from the server-- more and more images as might composer ultimately a map. And indeed, let me go ahead and open up the following. In map dot HTML is a relatively short page that has a few characteristics. The top of my page. I've got some CSS. To be cleaner I could factor this out to a separate file but I wanted to keep the demo in lecture pretty succinct. So everything's in this one page. HTML, body and hash map. So the commas in the CSS declaration here just mean, apply the following properties to the HTML tag and to the body tag and to whatever element has this unique ID. I want to make sure all three of those are 100%, because by default your web page has no height. Because if you have no content there's no height. But I want to make sure that my web page literally fills the browser. And I don't want any white margin around the edges. I want everything flush up against the sides and the top and the bottom. So that's all this does for me, nothing more than those aesthetics. Down here, in the body of the page, notice that I have quite simply a div that has nothing inside of it, open tag close tag, but that has unique ID called map. This is really a place-holder where I want to put a map. Down here I have my script tag. And I could have put this in the head page. Really what I've done is mimic one of the getting started examples in some of Google's online documentation, so that if you'd like to play along further, you'll see that this lines up almost perfectly with some of their getting started exercises. Indeed, even the function name I have here, INET map mimics theirs. And you'll see too, even though in Python, or rather not in Python, in C, we generally put these curly braces on the same line. You'll see that stylistically, probably more common in JavaScript certainly to do it on the same line here, even though the closing brace ends up over here. Again, all that matters is that you are consistent with respect to your own code and nice and neat. So what's going on inside of this INET map function, which I know to implement because Google told me to by reading its documentation. Go ahead and declare a variable called map. Go ahead and instantiats-- it turns out that JavaScript allows you to create or instantiate new objects, much like you can in Python. And JavaScript though, in this kind of context, you need to say new, which says to the browser, kind of like malloc, hey, browser, give me memory four-- although we're not managing memory like we do at a low level in C for a map. And Google dot maps dot map, you can think of as a class in JavaScript that represents a map. Like literally a world map. It's not technically a class in this case here, all the newer versions of JavaScript will introduce that and other features. But this is Google's way of allowing me to specify hey, Google, I want to map at the location identified by this unique ID. So document [INAUDIBLE] gets me that div, because its ID was quote unquote map. And hey, Google, here's how I want you to configure that div. I want you to center a world map at this latitude and this longitude-- which based on some googling is apparently roughly the middle of the United States, arbitrarily. Zoom level is four. I want to be able to see a lot of the country, not the whole world because then it won't fill the page. But I don't want to just see some middle state for instance. I want to be zoomed up higher. And I would know what number to use by trial and error or from the documentation. Then I want two markers. I want one marker, one little red pushpin on Cambridge, one pushpin on New Haven. And from some googling, I found that the latitude of Cambridge is roughly 42.3762 and the longitude is negative 71. And New Haven's 41 and negative 72, give or take. And the map I want those markers to be positioned on is map. So map is the key, per the documentation. Map is also the name of my variable. A little confusing, but it also keeps things clean because I mean what I say. So with just these few lines of code, I have implemented a function called INET map, whose purpose in life is to instantiate a map-- create a map, and put it in this div. Then with these chunks of code, I'm saying give me a marker, a little pushpin, at this position. Give me another marker at this position. That's pretty much it. The only other thing I'm doing in this page, notice, is this. At the bottom of the file I have a script tag whose source value is this long URL. It's got a key, which I signed up for earlier. And indeed, if you want to play with this example, you'll have to go to Google's documentation for the JavaScript API-- Application Programming Interface-- for Google Maps and sign up for your own key, paste it in there so that it actually works. But what's key at the end of this line is this call back. This is just Google's way-- it's completely a design decision of their own. But they have configured their documentation and their back-end code base to say this. Tell us the name of your function, because as soon as the Google Maps server hears from you, we will call this function of yours, as soon as the Google Maps API is ready. And I keep saying API. API is just application programming interface. It's a generic way of saying, someone else has written code that you can use, and the API describes how you use it. Indeed, when I keep saying, I've read the documentation, I've read the documentation, I really read their API or some human-friendly version there of-- a user's manual. And for instance, their API prescribes that this special object map it takes in a reference to the elements in which you want to put the map. Then it takes in an object as implied by the curly brace and the curly brace that takes at least these keys, the center of the map, and a zoom level-- or at least those are the two keys that I'm using. Meanwhile, the API for Google's marker specifies that you should also pass in an object, per the curly braces, that gives it a map on which to put that marker, that pushpin, and a position at which to put it. And I'm just doing that twice. So application programming interface will mean a little something different in real terms depending on whether you're using Google or Bing or any number of tools completely unrelated to Maps. But it just refers to features-- functionality that someone else has provided that you can then integrate typically into your own program. So what if I now visit Map dot HTML? What do I get? I get a map of the Earth, or of the United States in this case, centered roughly around the middle of your country. And then I have a marker here for Cambridge, a marker here for New Haven. But, notice, this map has so much functionality built into it for free. I can click and drag. And notice-- and if you look quickly-- well now we are literally over the edge of the Earth. So let's go back. If you do this quickly, you'll see that those rectangular gray spots appear. And that's because, at that moment in time, Google has not yet downloaded the images, the pings or whatever they are, PNGs for that part of the world. But, notice, if we do this. If I go into my Chrome tools and open up my Developer Tools and watch the Network tab, notice what happens every time I click and drag. Each of those rows in this table at the bottom represents another HTTP request. And a lot of them, notice, are pings. So really useful when developing JavaScript code is to watch the network tab because you can see your own data or someone else's data coming back and forth for you that's then somehow being used by your JavaScript code to update the map. We in our previous example were updating a price and a name of a company on the screen. But in this case, Google is clearly updating images on the screen after having initially drawn these markers. And if I now go to the Elements tab here in Chrome, you'll see that script tag that I had before, and this other script tag, which contains my own JavaScript code. But notice this. Div ID map, which was previously empty-- let me zoom in. If I expand this triangle, apparently inside of that div now is another div. Inside of there is another div. Inside of there is a whole bunch of divs. And indeed, this is what Google's Maps API has done. They have dynamically generated, using JavaScript, all of this HTML. I didn't write any of that. All I gave them was an empty div with a unique ID of ID, and the Google Maps API, upon being told where to put this map, has filled in that blank so to speak with a whole lot more content from its server thanks to JavaScript and thanks to this technique known as AJAX. Meanwhile, we can zoom in and out, because in addition to that drag handler that you see there, there is the plus sign over here. There's the minus sign over here. There's the satellite map, where it's going to re-download all of the tiles all together. So all of these features-- this is my website. Like, I made this. Well, I made this. All I had made was an empty div and maybe a dozen or so lines of JavaScript code. But this is again where programming gets really exciting and really fun, because you can start building things on top of other people's work in a way that they've made available so that you can do this. And if you think about apps you might have in your pocket, Lyft or Uber or the like, those apps have maps built in, right. And Uber probably didn't go around the world with cars or other technologies, figuring out where all the roads are. Rather, they're probably using Google Maps API or something like it, in order to show you those maps. And they built their business on top of that API. And this is again where things get really powerful, really quickly. Now there's another feature still. And just to show you that we're only scratching the surface, let me open up something like this so that we've at least filled in one gap. Earlier today we started with the alert function, which really should never be used. If you ever see a website that has that ugly alert pop up, that is cutting corners, just as I have because I wanted to focus on the ideas, not on the printing of information. But this underwhelming button at first glance, has actually been implemented using Bootstrap. So that's why it doesn't look like a default button. It's got more of a nicer gray border around it, even though it's still there in the top left-hand corner. But there's an event listener on this button for on click. And when that button is clicked, we're going to see an alert, but it's an alert that's a lot nicer. And maybe it's not perfectly beautiful as you would have it, but it's being generated entirely with JavaScript HTML and CSS. It's not the browsers built-in default. And indeed, notice what just happened. The back of my screen went kind of gray. There's this nice drop shadow here. There's a title. There's a body. There's a close. And for convenience there's this little x up here. And that's because Bootstrap, the library to which I've been referring, has bunches of other features-- not only these things, called modals, which are fancier alerts. And indeed, notice what a modal does. It deliberately, by design, blocks you from seeing other things until you dismiss it. Now it's dismissed itself and it's gone. But these are the kinds of features you get with JavaScript. So form validation, maps, interactivity like that. We're really just scratching the surface. But at the end of the day, it just boils down to a few features. And it's these libraries that take advantage of features like that. jQuery, which you can take a look at in a bit more detail here. Bootstrap, which again you'll recall from CS50 Finance, but you can see more about it here. It doesn't just come with CSS. It comes now with JavaScript capabilities. And then this is the URL of that other library that uses Bootstrap and gives us form validation. So let's look at one last example so that we can now tie together what we did some weeks ago with what we're now doing in JavaScript. It turns out that in C we of course manipulated images for forensics problems and whodunit and so forth. But you can do this in JavaScript as well. In fact, if you go to this URL here, there's some fun, exercises if you will, from our same friend Nick [INAUDIBLE] from Stanford, whom you may recall starred in that binky claymation video. Well, what Nick has put together online is a bunch of JavaScript examples that give us puzzles like this. So iron image puzzle. So here's something, not just with red noise, but with red and green noise still. And no matter what angle I look at this one, I really can't tell what it is. And it's not actually one of those magic eye things where you just kind of stare through it and something appears. Rather, there's a lot of noise here. And there's that image hidden. If we actually read the information here, we'll see that it contains an image of something famous. However, the image has been distorted. The famous object is in the red values. However, the red values have been all divided by 10. So they are too small by a factor of 10. So it's like Nick turned a knob and ratcheted down all the red by a factor of 10. The blue and green values are all just meaningless random values, noise, added to obscure the real image. And Nick tells us, you must undo these distortions to reveal the real image. First, set all the blue and green values to zero, to get them out of the way. Look at the result. And then if you look very carefully you may see the image, although it's very dark. So at which point we can multiply the red values by 10. So let me go ahead and do this. This now is using a simple image API that Nick has provided here. And I know this only from having read through his documentation, poking around the source code and understanding what exists. And I gleaned, by poking around and reading his documentation, that there's at least six functions or methods associated with this simple image API. This API doesn't get more data from the server per se. It's just an API in the sense that it provides me with a set of functions that I can call. So these functions include, get red, get green, and get blue, and set red, and set green, and set blue. And it turns out that Nick's already given me some starter code here in JavaScript. And I can now add some additional code inside of these nested for loops. Because much like your own forensics piece set where you probably iterated from left to right and top to bottom over your image's scan lines and pixels, so can we do the same in JavaScript as follows. So Nick suggests, and I'll take that advice, that I should first set the green and blue to 0. So I'm going to do IM for image. And that's the variable he's defined up there. And just for good measure you can think of this identical as before. We'll make it just like we did with our variables declarations. Image dot sets green at location x, y to 0. So again, I know the syntax for this API only by having read his documentation. Image dot set blue at location x comma y to 0. And Nick has given me this handy run save button. Let's do that. He is right. So this is another copy of that blue and green image. And I definitely can't really make out the image. I mean, it looks like-- there's a little bit of red there. I can actually way up close here-- and perhaps on your screen you can see the faintest of red. Let me enhance that. But the red is there. The information is there. I've set all of the green and blue bytes to 0, but there's still some red. I just need to bump that up. Well let me go ahead and do something like this. Var red equals image to get red at location x,y. All right. So let me do, image dot set red at location x,y, equal to red times 10, as Nick suggests. Click run save. Ho, ho. It's all very red, but now I can clearly see the Eiffel Tower. So we're really just scratching the surface now. I mean there's this whole field of steganography, the art of hiding information within images, for instance. And this is just an example-- a simple example at that. But notice the things that we did in C are all the more possible now in Python, or are just as possible if not more possible in JavaScript. But it's ultimately the mental models that are important. There's no server interactivity here once we've downloaded this page. We have been using today, JavaScript entirely on the client side. Which is to say that even once you've download an image, can you permute that image, in memory, in the browser, to manipulate it here. Or we could have sent it to Python. You could do the exact same kind of thing in Python. Use the appropriate library with extra read, those pixels, and those RGB triples if you will, and do it server-side. So it really just depends on what problem you want to solve. It did JavaScript itself, by a framework called node js can be written on the server-side too. You don't need to use Python or PHP or Ruby or Java or anything. You can use JavaScript. And as an aside, JavaScript has nothing to do with Java. It was really just a marketing ploy at the time. But JavaScript is the programming language that is typically used in the browser. It can be used on the server. And its syntax is exactly what we've seen here today. But it's especially useful in the context of web pages because it gives us a language with which we can manipulate the DOM that we've seen, the tree structure. It gives us a language with which you can change and add to and remove the HTML, and the CSS, and really anything you see. And indeed, it's this trio of HTML, CSS, and JavaScript, coupled with some back-end, Python or Ruby or PHP or Java or C+ or anything else, that together implement today's web apps. And so now with that, have you the vocabulary, coupled with SQL and your own database back-end to build most anything you want in the world. This was week 10. SPEAKER 2: Like I said, I don't know anything more than you do. SPEAKER 3: There must be something from your grad school days. SPEAKER 4: Hey, man. Not going to the party? We really should get started on that [INAUDIBLE]. It's a doozy.
B1 中級 美國腔 CS50 2016 - 第10周 - JavaScript (CS50 2016 - Week 10 - JavaScript) 18 5 小克 發佈於 2021 年 01 月 14 日 更多分享 分享 收藏 回報 影片單字