Video: Building Dynamic Websites at Harvard – Lecture 6
>> Okay, good. So just to summarize, if you have a relational database, inside of which is at least two tables and one of those is a primary key, like an ID, and another of those is the same ID but not in the same kind of relationship. You can join those two tables on that shared ID so that you get back essentially the union of the rows from this table with the corresponding rows from this table. And when I said it's the idea is a little bit different in the second table, we call this a foreign key, because it's there not necessarily to uniquely identify the row but to somehow link that row back to a corresponding primary key. So what was an example that we did involving primary and foreign keys? >> We had an inputting table and then we had a sales table — >> Okay. >> — so we joined the actual sales to the [inaudible]. >> Okay, good.
So we had an order — a sales table, an orders — sorry. We had products, we had orders, and there were some keys shared among those tables, for instance, an employee ID. Sorry, we had an employees table, and we had an orders table, and the shared key between those two tables was some employee identifier. So what's an upside of actually factoring out something like an order into an orders table? What was the motivation for introducing two tables on Monday as opposed to just one bigger table? Like if we already have an employees table on day one and we only have that one table, why not just add another column that lists the product ID that that person sold? Jack? >> [Inaudible] a whole lot of redundant information that's taking up space on wherever [inaudible]. >> Okay, good. You could end up with a whole bunch of redundant information.
For instance, if you clutter the employees' table with all of your orders you might have Jack, Jack, Jack, just because Jack sold three different items, and we certainly don't need three different copies of his name. And alternatively, if we didn't — if we weren't as bad as that, if we didn't actually just duplicate Jack's name or the employee's name again and again, what if we instead just put another column in the employees' table? >> Well that wouldn't be good either because that would be like faking a table because you would have to use commas or some kind of [inaudible] characters to actually identify the individual sales. >> Okay. So, okay. So, you've interpreted my proposal of another column, let's call it the orders column, as potentially containing zero or more order ID's, or product ID's, and we would have to resort to some kind of hack whereby we just separate those product ID's by commas and at that point we might as well just have multiple columns.
Okay, so let's do that. That was a stupid mistake I made the first time, let me have one column per order in the employees' table. Why not go that route? Why introduce this additional complexity of a whole other table? Let me sort of — let me play naive for a moment. So what would I name this column? I'm going to call it Order One. What would I name the second column? Order Two. What do I name the third column? Order Three. Now, start to find faults with my proposal. Jack? >> Well, so you have one customer — well, one employee that sells, let's say, 300 items. >> Okay. >> And another who sells maybe two or three. >> Okay. >> First of all, now you have 300 columns in your — >> Good. >> — table, which is way more than you need for the one who's only sold two or three items. And let's say if you [inaudible] the customer that sold 300 items but you want to keep the sales you wouldn't be able to do that because they're all on the same page.
>> Excellent. So a couple problems arise here. One, the table just gets really wide. For instance, to handle an employee who has sold as many as 300 items you now need Order One, Order Two, Order dot, dot, dot, Order 300. Which literally means 300 columns, but remember this is a spreadsheet of sorts, it has rows and columns and it has the same number of columns for every one of the rows, so now just because you have a really good salesperson he or she has 300 orders to his or her name, but suppose the norm is far fewer than that. Or you have a guy who's not doing so well and he only has two orders to his name, well you're wasting it seems a huge amount of space. Even if we've not filled in the blanks there's definitely some overhead involved in having all of these columns there for all of the rows.
So you just have this very ragged edge to your table whereby it might be 300 orders long, it might be two orders long, but this doesn't feel like the best design. As moreover, as Jack points out, if you delete or fire an employee, you're going to lose in this model all of his or her order numbers, which doesn't seem ideal. Now we can mitigate that one by instead of deleting the employee we could just have another field that's called terminated and it's one if yes or zero if no. So that might mitigate that but still this doesn't feel like the cleanest design. So the where we ended up on Monday was pretty good. So the [inaudible] schools table still had some other faults with it but at least this factoring out of orders and having it as a distinct table from employees was a good thing because we can always recover the relationships by doing joins, whether implicitly or explicitly. So what was the analog now for project one? Even though you probably haven't dived into it yet project one involves stocks, and portfolios, and users, and so forth, so what's the similarity there with this project? Axle? >> Maybe you would want to have one table containing all the portfolios on your entire site.
>> Okay. >> And another table containing all your user names and passwords. >> Okay, good. So maybe you'd have one table for all of your portfolios. And on Monday we defined a portfolio somewhat arbitrarily as being a stock symbol, a quantity, and it also had one other field associated with it, in the portfolios table. Stock symbol, quantity, and? >> Sales price? >> Could have sales price if we wanted to remember that information, but we crucially need one other field in this portfolios table. Yeah? >> How much money is [inaudible] sorry. >> Okay. Retracted. So I've got my users table, now I've got my portfolios table, and at the moment my portfolios table only has quantity and symbol. >> You need to tell — you need to [inaudible] which user actually has [inaudible]. >> Exactly.
We need the user ID. We need some kind of identification for the user so that we know who owns four shares of GOOG, in the case of a Google stock. Now we could store price if we did care about that history, and that's ultimately up to you, the [inaudible] allows you to simplify and allows a user to sale all of his or her shares, not just individual ones. So you don't really have to know exactly which of your shares you're selling. But that could be a compelling feature. Now in terms of this user ID, let's go there. In the users table we presumably have a username, which might as well be email address, password, or a hash thereof. Shouldn't be storing clear text passwords even though we did initially for John Harvard. What should the primary key be in the users table for project one? And again, don't take this as law, different designs are possible, but what could be? Yeah? >> A unique identifier. >> Okay. Unique identifier, I propose an email address.
Like it or hate it? Or do you like it or hate it? >> Well, you can do email address. >> Okay. So you say, okay, you kind of like it. Email address, who dislikes email address as the unique identifier as the primary key for my users table? Ben? >> It seems to be easier just to use a number. >> Okay. >> If you're [inaudible] who owns [inaudible] a number [inaudible] link that to an email address. >> Good. So just to recap, the upside of using a numeric identifier, like an int, that just auto increments, would be one, it's a little more efficient because you just search on a 32, or 64-bit value rather than some arbitrary length varchar. And you can also index it a bit more readily because there's just less — there's fewer bits to actually index. So it feels like that should be higher performing, certainly for large datasets. Jack? >> You're also saving space from also repeatedly putting in whatever someone's email is and however long it is when you could just be putting in some sort of — >> Exactly, so the space savings can certainly add up because if this user owns a lot of stocks and his or her email address was in every row of the portfolios table it just feels kind of ridiculous to store 10 or 12 or 20 characters just too uniquely identify that user.
Moreover there's another problem that would arise. Suppose that I wasn't this savvy, I didn't use numbers, I just used email address. Think about other corner cases that arise — could arise, not necessarily in project one, but if you continue to roll out project one as sort of an actual commercial website. What's a design flaw you might regret a few months later? >> Email addresses change, they disappear [inaudible] password. >> Good. [ Inaudible Speaker ] Good. So you leave Harvard and you lose your Harvard.edu address. You leave your company; you just decide you got to stop using that AOL.com address. You want to change your email address. Now what's the implication? Well, you the programmer could certainly allow a user to change his or her email address, but how many different tables or rows are you going to have to update now? If they change their email address you have to minimally update what? >> You have to — if you have a separate table for user ID's and emails then it's easily done you just need to deal with that table. But if you have it on all stocks it's a mess.
>> Exactly. Right? You have to do an update on the users table, you have to do an update on the portfolios table, or wherever else you've used it. And then there's the issue of well, how do you do that all atomically because it'd kind of be ideal that this kind of change happen all at once and not a little bit of change over here, then over here, then over here, because for whatever reason if that user decides to hit reload in some other browser window in which they're already logged in you could end up with some very funky undefined behavior if some of your tables have firstname.lastname@example.org and other tables have email@example.com, just because you happen to look at your database while that change was in process. Jack? >> And beyond that if you do have some sort of [inaudible] atomic process so it does it all at once you're going to shut down the — using the SQL database for all the other users who [inaudible].
>> Well, good. So if you resort to lock specifically and you're using MyISAM tables, which was one of the formats that you can have for a table, then you would indeed have to lock out other users. In this case you could use NoDB, which now is in fact the default, and transactions would not be as — would not have the same impact on users. So we can at least mitigate that. But there's then at least the additional complexity of just updating all of these darn tables just because you made a foolish design decision upfront. So, realize that when I say there's many different ways of doing these things, it's fine if you still for this project, for instance, want to use email address as your identifier, but you're going to have to justify that to us. For instance, in the [inaudible] that you were asked for project zero and also now for project one, you're invited to explain your various design decision, so if you feel strongly about something that's fine. But what we're really looking for when evaluating projects is did you give it the thought and did you make a judgment call as opposed to just picking something because it seemed easy without really thinking through the implications? So do be mindful of those kinds of things.
So in terms of project zero, it has been distributed among the TF's. You should soon, if you haven't already, heard from your specific TF. We have a team of four this semester and so they'll be reaching our via email and they'll also be providing you with feedback, both numeric and qualitative on the project, and the aim is to get that feedback back to you at least a day or two before the next project's deadline so that you can absorb that feedback and make any last minute changes to your current code for project one based on any repeated mistakes or decisions you might have made that maybe weren't optimal. So feel free to reach out to me and also to your specific TF via email anytime if you have questions.
So, in the case thus far with document it turns out there is a property called forms. Forms happens to be a collection of all of the forms in that document. And there might be zero forms, there might be 10 forms. It totally depends on how many form tags are in that document. So document.forms.login specifically means get me the form whose name is login among all of the forms in the current page, whether there's one or more. Document.forms.login.username, take a guess here, what is username referring to in the context of this story thus far? Axle? >> Well, [inaudible] field of the ID username inside of that form. >> Good, so in this case it's referring to the input called username, happens to be name as opposed to ID in this case. Username field in the form whose name is login in the collection of forms inside of the DOM. So there's a hierarchy to these dots, just like in Xpath and in the simple XML API there was this notion of stepping where the arrow notation that said go deeper, go deeper, go deeper.
Next, I have another input called password1, and then third I have another field called password2. So you can imagine this being in the context of a registration form. So not necessarily login but registration where you want to ask the user for the same password twice, that'll lend itself to some validity checking in just a bit. And then lastly I have a submit button. So that's it. Well, what if now I want to start getting programmatic access to these various fields, let's do this. Let's open up instead version two of this, form2, and let me propose the following approach. Down here now let's do a registration form. So I've given this form an ID, registration, and I have given it similarly an email field, a password field, another password field, and then a submit button.
So we didn't see this one but under what circumstances would I have been yelled at with, "You must provide an email address?" Yeah? >> If you didn't enter anything at all in the email field. >> Exactly. If I had not typed in Malan, but I just left that field blank at the very top of the form, I would have been yelled at with this message. And just to be clear, why do I not only call alert, I also return false? Isaac? >> Well, it has to be false or true on submit. >> Okay. >> So it has to return true or false for the sake of the onsubmit handler, but why false, just to be clear? >> So that it doesn't [inaudible]. >> Good. So that the form rather doesn't submit fully.
I could trip leading white space, I could trim trailing white space, and that just means throw it away so that even if the user's trying to be difficult or annoying by just hitting the spacebar to get through my stupid prompts I can still catch at least those scenarios. To be clear though, I'm not doing anything like checking the length of the password, I'm not checking whether it has enough alphabetical characters, numeric characters, punctuation characters. There's no like security checking here of the quality of the password. We're just seeing if the user gave us anything whatsoever. What about the third branch here. So else if document.forms.registration .password1.value ! equals ""document.forms .registration.password2 .value then yell at the user as well. And before I spoil the answer, in English what should the error message probably be? What have they failed to do properly here? Yeah? >> You need to enter the same password twice.
>> Exactly. We need to yell something like, "You need to enter the same password twice." Because the logic I just checked was did password one's value equal password two's value? If not, they screwed up again and they typed the wrong thing twice. So, if you've ever been on a website that does exactly that kind of check this is similar to the kind of code that they're writing. Theirs is probably a little more compact, we're doing it the very pedantic way just for now, but the functionality is the same as you would find on a typical website. What's this last block doing? "You must agree to our terms and conditions." Why does the code in that — how does the code in that branch work apparently? Yeah? >> Well it looks for a dot checked on agreement, which is probably the checked box. >> Good. >> And the exclamation mark in the beginning of it says if it's not checked, so then you run the alert. >> Exactly.
I seem to have a fundamentally different approach here, and before we dive in what is different about this function, this version of validate? Yeah? >> It takes the argument that you call f, which is probably going to be everything before like .command, .form, and everything. >> Okay, excellent. So it looks like this version of validate takes an argument first of all, and that argument's apparently called f, because it's in parentheses there. And I seem to be using f subsequently further to simplify my syntax and more generally because what I'm going to do in this version as we'll see after a short break is that I can pass around even forms themselves as arguments because a form in a webpage, once it's read in by the browser, is represented as a node in a tree, as one of those rectangles that we might have drawn a couple of lectures ago. And so I can pass around a reference to that DOM node, that form node, and indeed this case we'll soon see that the variable f, the local variable f is going to be of type node. It's going to be a form element that was passed programmatically. Why don't we go ahead here and take our five minute break and when we return we'll see exactly how we did this and what more we can do with objects from DOM's.
So we have this way now in code to refer to the HTML element that we know eventually will be accessible via that DOM object, that document object. All right, so return validate this. Now let's look at what the implication is of this calling convention. So if I scroll back up to the top where my validate function is defined, recall this is where we left off a moment ago, and the validate function takes an argument f, arbitrarily called f, I could have called it foo, bar, or baz. But thereafter I can specify f.email.value, f.password1.value, and so forth. So one, my syntax has gotten a little simpler, which is nice. Two, I now have the beginnings of more reusable code. I now have a validate function that in theory could validate any form object that has these particular fields of the email, and password1, and password2, so I've begun to at least start factoring out what could be some common functionality. And three, it really demonstrates, hopefully, that via the this keyword we now can bridge the gap between HTML, which is really just markup, and programming code.
So, when you check this, let me go up to this in a browser now. So this is now form5, notice that it's a little subtle here, but notice that now that submit button is a little grayer than usual. All right, well maybe that's just a CSS thing, but let's try to click it and be a difficult user and not fill out anything. I'm clicking, nothing's actually happening because that is in fact disabled. So why is it disabled? Well, this was just a design decision I made in this version whereby I only want the user to be able to submit this form if they have minimally given me what I wanted or at least minimally checked that box. So let me go over to that checkbox and see what happens. Checking now, and notice the difference at bottom left. Every time I check or uncheck that box the submit button changes state and once it is black like this it seems to let me click it again, I'm not actually letting the form be submitted but if I clicked it it would go through.
Thankfully I now have some error checking still in place but more on that in just a moment. So how are we actually doing this? Well, if you were writing the code yourself and you want to tie that button somehow to the checkbox, what was the property on the checkbox element that we want to be checking in order to decide whether or not the submit button should be enabled or disabled? Yeah? >> Dot checked. >> Dot checked. So it turns out in addition to dot checked some elements can have a dot disabled property which literally says should the browser let the user click it or not, is it disabled or not, true or false? So if we go back to version five of this code, let's scroll up here to the very top, or rather, let's first look at this. Notice that on the right hand side here, I agree to these terms and conditions, then I have input name equals "agreement" as before, and now I have another event handler.
So I've done something a little different here. I'm not using onsubmit because I don't want this form to change states when I submit the form because that's too late; I want it to change state when I click on this checkbox. So in English, what does onclick equals "toggle ; mean, or do, do you think? Yeah, Ben? [ Inaudible Speaker ] Exactly, simple as that. Anytime you click this checkbox call the toggle function. There's no arguments passed in, but as the name of the function suggests there should probably toggle the state of what? The checkbox or of the submit button? The submit button hopefully, right? The checkbox you get for free, you just have to check it, the browser will do that for you. So let's scroll up because it sounds like either there's a built-in toggle function or it's something I myself wrote and indeed it's the latter in this case. Here's my toggle function. Pretty straightforward, albeit verbose, if document.
forms .registration.button .disabled then set that same property equal to false, else if document.forms .registration.button.disabled — rather, sorry, else set it equal to true. That was not a condition. So in other words if it is disabled, make it not disabled, else make it disabled. So really I'm just toggling the state of that. I could actually do this a little more elegantly if you prefer. I could just do something like this. I could say document.forms .registration.button .disabled equals that. That's a slightly more elegant way of doing it. Right? I don't really need the if condition, but it's also still a little verbose. But again, we'll clean that up next time. All right, so that's the toggle function, simply toggles the state. What is the validate function doing this time? Well, it's pretty much identical to the very first version. There's no fundamental relationship between validation and the submitting of this form, all I've added this time is this onclick handle — handler and implemented the toggle function myself.
You know what I can do? Why don't I just go in here and just disable — delete this, enter, zoom out, well there you have it. Now my form button is re-enabled. Right? So you don't even have to be a good hacker to circumvent protections like a disabled property, you can just change it right there in that fashion. Or frankly, we can be really sophisticated here and if you really want to be a geek we could do something like, well, if I want to telnet to the server I can telnet — rather, if I want to fake a request, recall we can go back to lecture zero in our HTP request and mimic them ourselves. So telnet is a program that allows you to collect from a client to a server on any TCP port in this case. I'm going to connect to port 80 of the appliance. Now notice I've connected to 127.0.0.1, and indeed that's the loopback address.
However I could do this to Google, but rather I'm going to do this. So I'm going to say, rather, POST to — oh no, we're using get today. So we're going to use GET /process.php HTTP/1.1. I'm going to say my host is the appliance. And then — woops, notice I already got back my results. Oh, [inaudible], yep. So below that, I won't do the whole example here, what I could continue doing here is the equivalent of passing in — well let's do it. GET /process.php? email-malan&password1 equals asasas&password2 equals z HTTP/1.1, so this is definitely the geekier way of circumventing client side protections. I goofed somehow. Client site php, bad request, ampersand. What did I do wrong? Password. GET /process.php?email equals malan HTTP/1.1. I'm doing something wrong. Okay, anyhow, someone smarter than me could actually just mimic the HTP request to send them from a command line client or from a browser client and actually trick — oh, that's what it was. Okay.
key, is simplicity. It's just very readable and we've been using it all day long so far, document.forms .registration.email1.value. Been doing that the whole time. However, we could've used the square bracket notation it just wouldn't have read as cleanly, and moreover if you ever have keys that have funky characters in them, like spaces or the like, using the quoted notation with square brackets allows you to access those keys. You can't use the dot notation for more complex looking keys. In general though it's probably best to avoid anything complex in terms of a key. How can you create an object and assign key value pairs to it all at once? The very last line here is representative. So if you know in advance that you want to create an object and you know in advance what your keys and your values are, you can simply say, var obj equals brackets and then brackets key: value bracket; and if you want multiple key value pairs just put a comma after the value and do another key: value, key: value, so it's a way of creating an object on the fly with multiple properties.
So we'll see why this becomes so useful. How about event handlers? We've seen a couple, onclick. We saw another. What was the other one? >> Onsubmit. >> Onsubmit we've used a whole bunch of times. It turns out there's a whole bunch of others. Onchange, onfocus, onkeydown, onkeyup, onload, onmousedown, onmouseup, onmouseout, onmouseover, and so forth. Just to infer based on past experiences, when or why is something like onmouseover generally used? Even if you've never heard the phrase until today, when might that be used to detect when the mouse is over something? >> When you hover with the mouse over a [inaudible] field. >> Okay, so when you hover over a mouse with an input field what do you want to happen? >> Well, I really wouldn't want anything to happen, but if you [inaudible] or something you could — >> So you want to hover over a form field? Be more concrete here. We can recover from this.
>> You can — maybe you want to display some kind of info on something you have on your site, like an image, or a file thing. So if you have say a website that lets people download files and if they hover over the icon for the file [inaudible] like the file format and the size and [inaudible]. >> Perfect. Okay. So in contexts where you want to enable the user to hover over something like an image or maybe even a text field, and then you want to provide them with additional information, or additional functionality, then you can use the onmouseover even handler to reveal additional buttons, or to give them the equivalent of a tool tip, a little DIV or something that suddenly appears like a cartoon bubble that explains what it is they're hovering over. And these are omnipresent on the web. If you go to YouTube I think you can hover over most of the HTML5 controls on a player and see what those symbols represent. If you go to Netflix you can hover over a movie posters and then a little window opens and you can see more details about that movie.
How about onkeydown, or keyup, or onkeypress, which is yet another? When might that be useful? Someone else? Why might it be useful to listen for key presses? Whether the key is going down or going up? Scott? >> [Inaudible] how many times [inaudible]. >> Okay, good. So recording how many times the user types something. Maybe you could use that metric for forms that have only 100 characters or 140, like a tweet or something like that. It might be useful to count how many times the user has typed. Alternatively you could check string length in the value of a field, but counting might be reasonable. What else? >> I've only ever used it once, but when I used it I had like input field and when users typed anything in input field it updated [inaudible]. >> Okay.
If you don't want any spaces in a field, if you want to make sure that they have — if you don't want them to type in certain characters at all, or maybe it's a numeric field, you don't want them typing letters for whatever reason, you can use onkeydown because what you get with this particular event, you're not just informed that the event happened, you're informed what key the user has typed. So if you detect, wait a minute, that's the letter A, but this is a numeric field, you're supposed to be telling me your account number, you can just return false effectively and say, ignore that particular A the user typed in. So some websites do this too to prevent you from pasting. For instance, Amtrak.com, absolutely hate their website because my email address is in my Amtrak profile and they have this stupid feature where you have to confirm your email address, once and twice. And I'm okay with the principle of confirming your email address because a lot of people, myself included, make mistakes when typing it, but their damn website prevents you from hitting command or control-V.
Which means you can't paste your email address into the field, even if you are absolutely certain that it is correct from the previous field, and that sort of drives me nuts. Other objections I have to people's websites include — actually there's an unnamed website at Harvard that when you're trying to buy something they want a 33-digit billing code, those of you who work at Harvard might know of these things. It's god-awful; I have never memorized a single 33-digit billing code. I copy and paste it. Their website doesn't let you copy/paste a billing code so you have to manually type it out, which I daresay is far more vulnerable to mistakes. But anyhow, what's the pedagogical value of this rant? This is how you would implement such annoying features as those. There are better of uses of this. Right? If you're a Gmail user you might use some of the keyboard shortcuts, C for compose, A for archive, or the like.
How does Google listen for those keystrokes? Well they're listening for A, they're listening for C, they're listening for other keystrokes as well, and they're not rejecting those keystrokes per se, they're actually doing something useful based on them, and that's all because the web browser world is very much event driven. Stuff happens, you hover, you click, you type, and you can listen for all of these events, and this is how you make all the more dynamic of a website these days. How about something like onfocus? What does focus mean in the context of a webpage? Yeah? >> Well if you have an input field and you click it or you tab to it it's going to be focused and that's when you essentially edit the value of it or type something into it. >> Exactly. So in the context of a webpage only one element ever has a focus at even given time.
When, by focus you can think of it very concretely as you've said, like a text area. When you put your cursor in a text area indeed in some browsers it kind of gets highlighted in blue or at least your cursor starts blinking there. That means that form element has focus. If you hit the tab key on a webpage you'll generally see a little blue or whatnot outline move from element to element in the webpage. That means that element has focus and it's just a visual indicator for accessibility purposes as to what you're actually hovering over, because generally you can hit enter or the spacebar at that point to activate whatever it is you're hovering over, or rather, whatever it is that has focus. Blur is the opposite. So when might you care that a user has blurred some form element? In other words, blurring means it's no longer focused, it doesn't mean it gets blurry or anything like that. Isaac? >> Well you can do form validation after they click another element. >> Yeah. Exactly.
It might be annoying and it might not be necessary to check a form for validity with every keystroke, right? And obviously when I start typing my email address it's not going to be valid the first few characters, right? You got to give me some time. So maybe we could instead wait until that form field has blurred in order to check whether or not it's a valid email address. Or we could wait even longer and wait until onsubmit, but onblur gives me that capability. And others, onresize? Onresize is actually a powerful one. If you're building a website that really has some predetermined size and you want that size to grow when the user changes the webpage around, potentially you need to listen for onresize so that you can do some math on your own webpage and make things wider or taller or shorter.
They represent all of the blink elements in the DOM. So at this point in the story, blinks is an array of zero or more of those tags. What comes next? Well, we have a variable. Notice that you can declare variables inside of a for loop, just like you can in some languages. So var — for var i equals zero, i is less than blinks.length i plus plus. Well, we have a new feature here of arrays it seems. Blinks.length obviously represents the length of the array, but what is length really? Well, it's a property. Again, objects have properties and array is an object, so blinks.length is the length property of the blinks array object. All right? So what comes next inside of this loop? Well one, I'm iterating over all of the blink tags in the page, and what do I do? If blinks [i].style.visibility equals equals visible, then change it to hidden. So, this is actually a CSS thing. If unfamiliar, a element on a webpage can be "visible" or it can be hidden and those CSS properties do exactly that.
That dot style property is essentially equivalent to the style equals "attribute" that we could have put in the HTML. So it's the CSS stylization for that element. We can now say change the visibility attribute to be hidden instead of visible, else, do the opposite, that's all we're saying in the else. So just to be clear here, let me bring up a little scratchpad for a moment. Just to be clear, if I had done this in my style sheet or in my style tag, I might have something like this. Blink — this is CSS now, I might say visibility visible, so that's the default, so it would be kind of silly for me to put this in a style sheet, but that's what I've just done. What the if condition is doing is it's changing this effectively to this — on off, on off. So what's the aesthetic effect? Well, let's take a look.
Let's go back to the browser and let's pull up this one, which is in a form example, this one here is the blink.HTML and you can see what it's doing. Right. Hideous tag, you know, it's not all that annoying here, but if you see — actually you can still see remnants of this on the web, like really crazy looking websites that are trying to use the blink tag, but it just didn't work. So let me scroll up here because this is actually kind of interesting. Let me zoom in over here and you can see thanks to Chrome exactly what I'm doing. >> I have a question. >> Uh-huh. >> Is — are — on this page, are you using the same script you had in the PDF? >> Same — yes. >> Because in the PDF, it iterated over the number of blink elements, which in this case is just one. So wouldn't that be one — one iteration, just [inaudible]? >> Ah, correct. So, I'm using the same blinker function, but I'm calling the blinker function a little differently.
So let me open that up. Let me go into blink.HTML, here's my blink function, but there's one additional line of code that's necessary here. What is this very last line of code in my script tag doing apparently. Jack? >> It makes sure that it won't [inaudible] again until, I guess [inaudible]. >> Good, although let's not put it that way because it doesn't really make sure that it won't call it, because it's only going to call it — it's not going to call it at all based on the code I have here. >> It makes it call it once in [inaudible]. >> Good. So, window.setInterval is a method of the window object, which we've not seen before, but it's another one of these special top level objects. Just like you have document, which represents your actual document, window is a different object that represents like a chrome on the screen, it lets you do things like window size redetection and so forth.
So window has nothing to do with the HTML, really has to do with the browder — the browser, the — the rectangle that is your browser window. So window.setInterval does that. It sets an interval, which means call the following function again and again, every some number of milliseconds. So blinker is the name of my function, 500 means 500 milliseconds or as Jack said, half a second. So that line is simply saying, set an interval of 500 milliseconds whereby every time that interval happens, every 500 milliseconds, call the function called blinker. Now notice one key detail. I have not written blinker as a function call, I have written it as a function name. So it let me go here. This is wrong. I've just added to parenthesis, open paren and closed paren, that is wrong, but why? What's the difference? Or what would happen in this case here? Jack? >> It would try to see if blinker — it would actually call blinker right there and see if blinker has a return value that might be [inaudible] what it wants.
>> Exactly. So in this case, just like in all of the examples we've done this far, blinker open paren and closed paren means call blinker, right. There's nothing fancy there. The problem with that is that as [inaudible] that will effectively call blinker once and that's it. But what you're trying to do here is apparently set the interval of 500 milliseconds to call whatever the first argument is. Now does blinker return anything? It actually doesn't return anything at all, which means you have nothing to call. When it returns, it's not returning function, so nothing's actually going to happen on subsequent passes. So this is actually incorrect. By contrast, if I just say blinker without the parenthesis, that means pass in a function pointer, so to speak, pass in a reference to this function because what the window.setInterval timer will do is add the parenthesis effectively itself to call that function every few seconds. So we can do something with this. Here's how you make a really annoying webpage. But just [inaudible] here, let's hammer this home.
Actually be careful of doing things like this because if you do it too fast you have to like force quit the whole browser because you can't actually stop. Anyhow, let's go and rewrite this slightly differently. So, this — oh, my God, all right. So here, we can fix this. Let's comment this out, let's go back here, reload, okay. So now we've — now that should stop. All right, so what don't I like about this? Well one, the functionality is kind of annoying, but two, it's kind of stupid that I defined a function only so that I could reference it the next line down. Right. This is kind of a waste of your name space, so to speak. In other words, if you're only going to write a function once, and then call it in one place, it's not really fundamentally necessary to give it a name, right. The only reason it has a name at the moment is because I want to define it up there and then call it down there. But what if I could do both of those at once, especially if this is a throw away function that doesn't need to be called by anyone else or even by me anywhere else? So what if I instead do this? And the syntax is going to look a little weird for a moment.
So this actually looks a little cryptic, but it's just the natural progression of the various examples we did leading up to it. So in English, window.setInterval takes two arguments, one is the address of a function. The other is number of milliseconds. Doesn't matter how we pass in that alert function, we can still pass it in — we can pass it in anonymously. So what we've just done is used an anonymous function or something more fancily called a lambda function, which is simply in this case a function that has no name. But it will still work, so let's try this. Let me go back, save this file. Go back to the browser. And actually let's do it, instead of every five seconds, let's do every two. So the story gets told a little more quickly.
Hi, hi, hi, browsers thankfully have gotten smarter, so let's ignore this one. Back in the day, you would've gotten another hi, another hi, another hi, another hi, another hi, at which point you realize you should — really shouldn't have visited that website. Java — Chrome at least, is better about managing duplication, but that is not necessarily a given. All right, so any questions on anonymous functions? No. If you really want your mind to be blown, let me do one other thing. This is really just to show off and to get you thinking about more sophisticated syntax. Let me go ahead and get rid of the interval and just do var f gets function and we'll do the alert thing like this. So this is similar to before. I'm not called f yet, but if I wanted to, I could do this — f open bracket, all right. So let me go ahead here. Go to my appliance, reload — whoops, okay, reload.
And on Google's end, this is less that it has to send out to every user that [inaudible] page — >> Good. >> — Google [inaudible] site, they need to [inaudible]. >> Yeah, so a couple of reasons. Like one, like you know, normal humans like us, we don't need to see this, so it doesn't need to be pretty printed or well formatted with good variable names. It needs to be designed well underneath the hood, but aesthetically doesn't matter to us what it — what it looks like. And then performance, as Jack says, if you think about — it's kind of remarkable. If Google gets maybe a billion hits per day on their homepage, imagine if a programmer simply accidentally hit the spacebar at the end of the file leaving a single character of white space, not a big deal, right. We've all done it. We all do it quite often probably. But if a billion people are going to download index.
HTML today and this programmer hit the spacebar, how many more bytes of traffic is that for Google to transfer. Yeah. >> Gigabyte. >> It's a gigabyte, right, like a single space character for someone as big and popular as Google, it means they're going to have to transfer an additional gigabyte of information for no good reason. My God, what if he hit the spacebar twice, that's two gigabytes, 10 times, that's 10 gigabytes. So there's very real world implication, certainly for the Google's and Facebook's of the world. But even for your own website, like why bother wasting bandwidth on things like that when you can compress it once, still keep an original copy for your developer so that humans can actually read it and update it later, but the browser doesn't actually care. So this is a very common technique for that reason. And what's a third potential reason for wanting to make your code look more like this? Jack? >> If you want to kind of deter competitors from trying to find out how and why your code works. >> Good. So if you want to deter competitors from how and why their code works, you can try to make it look a little more like this, very easily.
So let's actually try one of these. Let me go to this one here. This is just a smart guy who's put this together. So these are actually reputable ones, the ones I put up. If you're trying to be sold any such tool, I wouldn't pay for it. Let me go into one of tonight's files so that we can dig up, let's see — let's go into tonight — whoops, let me pull up, let's see, will that work? All right, let's just try it, we don't need a whole example, we can do it by hand. So let's see — var annoy gets function, let's see if this works — alert hello closed brace semicolon, okay. So here we go. We're on this packer site, I'm going to click pack. Okay, so here's what I've just done to minify my code. You know, it's still quite readable frankly, we could all probably figure out what this piece of code now does.
But what did it obviously remove? [ Inaudible Speaker ] Okay, so white space is all it removed. I think this site has a few options here just to make this a little more interesting. We can shrink variables, so I've just check the box at right that says shrink variables. Let's pack this again. Now that really didn't do anything this time. So let's do base62 encode, what does this do? Okay, so this is what these sites tend to do when they claim their encrypting your code. So this is the same thing. What is that doing? What does that program do? [ Inaudible Speaker ] It prints hello, right. That's all it does. Now, all of this though can be reconstructed and frankly, this just, it's kind of a cute little [inaudible]. So notice this guy has define an anonymous function with the function keyword that takes six arguments, p, a, c, k, e, r just because he's being clever with his name.
So more on that to come. I'll stick around for one on one questions..