If ya need a review of closures, make sure that you take a look at Episode Two. Creating a constructor is pretty easy, and they look just like functions that have other functions in them; but because they're part of an instance of an object, these can perform actions that are called methods. Constructors are pretty cool, but it's definitely something that you'll need to experience to understand. Let's take a look at a common example. What we're going to do is build a hamburger menu. We've got sort of the core of the menu here, but it's not really working.
If we try to click on this one, doesn't really do anything. It is responsive. You can see that I'm using Flexbox to lay this thing out. So make sure you check out the episode on Flexbox, you want to take a look at how I did this. There's another menu at the bottom because I want to show you sort of how you can create instances for each one of these different menus. So, if we take a look at the index.html file, this pretty much looks like what we did in the episode on Flexbox, except that we've added this extra button right here and I'm importing some Font-Awesome icons just to get this little hamburger menu up here.
And I've given this menu an ID of topMenu right here. And there's another one down here that has an ID of bottomMenu. I've also given the sort of group of all of the menu items a class of navitems just so that I can target that with CSS. The CSS looks pretty good. I've added the CSS for the button right here as well as the hamburger button itself. I do have some special classes that I'm going to use for hiding the button whenever we are not in this small mode.
If I made this wider, you're going to see that that button disappears. It's normally hidden. And when I get to sort of a size that is smaller, it's going to show this button. Whenever we go past 600 pixels, it's going to not show that button, regardless of whether or not we click on it. Actually, we wouldn't be able to click on it if it was wider. We've set all this up, and all we have to do is create a script. And we're going to use this constructor pattern.
And what I'll do is create a function here, and I'm going to call this Hamburger. I'm capitalizing this because, by convention, whenever you use an object or a constructor method, you're going to capitalize this; you don't really have to, but it's what everybody does. And then, to this function we're going to pass a nodeName of which element on the page we want to activate with this function. Here we're going to create a variable that is going to point to a node; I'll call it myNode.
So we're going to do two functions here; one of them I'm going to call activate, and this is going to initialize our hamburger menus and make them collapsible. So, this is going to be an anonymous function, which means a function. When you create a function that returns an object like this, and this element right here is another function, we call this a method. Because we're going to be able to call hamburger, and then use one of these subfunctions. Notice that this is also a closure because this activate method, or function, is going to be able to use this variable.
So, let's go ahead and do my function here. It's going to target myNode because is available to me from this variable. Then we'll say addEventListener. And then we were going to add a click event, and do another function here, and that function, whenever we do an event, it's going to return an event object which we'll put in this e variable. And, we need to make this false right here.
And, let's go up here. And what we want to do is go ahead and make the navbar. If we look at the HTML again, we have the button itself, and then we have the navbar right here at the same level. So we want to sort of get to. Since the navbar and the button are at the same level, what I'm going to do is target the parent of the button because that's what I have on my node, and that's going to let you get to this navitems.
And then, from here, I can go down, and target this navbar element which has all these menu items. So, the way we do that. We'll say myNode, and then go to the parentNode, and then querySelector, and we want to target the item with a class of navbar. And, we'll use the classList method to go ahead and toggle a class that we're going to be calling hidden. If we remember from the CSS, we have a class called hidden.
When we're at a small size, that class will hide the element by using the display-none parameter right here. Right, let's go ahead and add some comments here. This is activate. This is going to be the return statement. And then, this is going to be hamburger. Now that we have that, what we could do is create a variable. And I'm going to target or call this variable topMenu because it's going to target the menu at the top.
And I'm going to say that this new variable is going to be a new copy of hamburger. Hamburger is the method that we created, and it expects us to give it an element to target. So we're going to target the topMenu here. And that's going to get us this hamburger menu right here. And then, what we could do is, once we have that object, we can say topMenu, and call our activate method for that topMenu. Let's go ahead and save. It looks like this is not quite working yet, and I can see that I made a small mistake here.
This nodeName should actually be capitalized over here. We do have to be consistent. I try to use camelcase, which is sort of with different words the first other word becomes capitalized. Sometimes that's easy to mess up. Also, this hamburger class right here that I'm looking for is a child of topMenu, so I technically should have a space right there. And, let's go ahead and save this, and check this out. And it looks like it works.
So, because we're only targeting this hamburger menu that's the topMenu right here, you'll notice that the one at the bottom doesn't work at all. So if we wanted to activate that one, too, we could do the same thing, just call the bottomMenu. So, bottomMenu. And, when this reloads, this one will become collapsible, as well. So that's pretty cool because we can create sort of a constructor that allows us to target different elements, and each element has its own environment.
In addition to using this activate method to do something like initializing our menu, we could create another method that does something else. Let's go ahead and add another one here, right after this activate method. Because this is an object, we have to add a comma. And, I'm just going to copy all this, and make sure that I don't use that comma on this second one. The last element in an object should not have that comma. This is going to be hide.
And I'm going to rename this method hide now. It's going to be a function. And, in this case, I don't need to add an event listener to this, so I can delete the event-listener part. And, it's going to be pretty much the same thing. Look for the parent element, and then use the classList. What I want to do here is add the hidden class if it doesn't exist. Now I have two methods, and one of them will allow us to hide an element, and the other one will allow us to toggle the element.
Let's go ahead, and make sure that the bottom one. Let's refresh this. By default, this one's going to show. And this one's already showing, but maybe we want this one at the bottom to be collapsed. Now I have two different methods. So I can say bottonMenu here, and use my hide method so that the bottom part of this is going to be hidden by default. Notice at the bottom, the bottom one isn't showing; if I scroll up, you can see the top one is; and if I click on this, you will see that it will appear and disappear.
These are configurable. The nice thing about these different constructors is that, because of closures, every one of these instances it's own environment, so we can control them differently because of how closures give you access to local variables of the different objects. Now here's a nice link on CSS Trick where you can get some more information about the constructors and also some related courses that you may want to consider taking. If ya have some ideas for this weekly series, or maybe you want to share with me some questions you've been asked or have asked in interviews, connect with me in LinkedIn or just about any other social-media network, like Twitter or GitHub, at Planet of the Web.
Skill Level Intermediate
Q: Why can't I earn a Certificate of Completion for this course?
A: We publish a new tutorial or tutorials for this course on a regular basis. We are unable to offer a Certificate of Completion because it is an ever-evolving course that is not designed to be completed. Check back often for new movies.