FREELessons: 29Length: 8 hours

Next lesson playing in 5 seconds

Cancel
  • Overview
  • Transcript

2.4 Events 101

[SOUND] Welcome to day four of learn jQuery in 30 days. And this is where we actually get to take some of the methods we've learned and begin building actual stuff which is obviously what you want to do. So, today we're going to be focusing on events, how we can respond to specific events that occur. For example, when an element is clicked on, when you hover over it, when you double click, these things are called events. So, to demonstrate how these work, let's build a little style sheet switcher. Essentially, you click on a button and it will load maybe the nighttime style sheet, and when you click on another button, it will load the daytime. And this will be a perfect way to detect and listen for when the user clicks on a button, and then respond accordingly. I will open up Sublime Text, and here we have a simple page, pretty much a boiler plate. We have our html. We're pulling in jQuery from google cdn, and we're all set to go. So, the first step is, we need to mock a website. I'll simply create an h1 that says My Website, and I think that's enough. I think that's a fantastic website. So now, I wanna add two buttons that will allow the user to specify whether they want the nighttime sales sheet or the daytime. Or you could imagine maybe you have a stylesheet for maybe younger people who can read smaller text and a different one where the font size will be much larger. Maybe the layout will be different for people who have a little trouble seeing the page. Nonetheless, we'll stick with the day and night. That's fairly common. So, to listen for these events, we can either use anchor tags, and listen for when that's clicked, but we're going to use a button in this case, because if you think about it, if JavaScript is not enabled, usually you use the anchor tag to link the person manually to wherever it is you're trying to go. In this case, there really isn't anywhere we would take them if JavaScript was disabled. They simply wouldn't have that ability to adjust the style sheet. So, in that case, I think a button will do just fine. We'll this first one the daytime button, and we'll call the next one the nighttime button. So, the next step is we need to have these two style sheets. So, we'll create them in the root of our project, day.css, and then I will create one more called night.css. Now, to simulate the difference between day and night, we're not gonna use any server-side or detect what time of day it is. That's not necessary for learning about events. But for day, we'll set the background to a sunny yellow, and then we'll set the nighttime, we'll set a background of black, and I'll make sure the color is white just so you can have some detection that this represents night. And this represents day. Now by default, when the user loads the page, we're going to give them the daytime style sheets. So, I'll pull that in, day.css, and let's view this in the browser. And there we go. That's pretty much what we would expect, an amazing website. So now, we're going to listen for when the user clicks on one of these buttons, and when they do, we're going to load the applicable style sheet. Let's go back and get started. I'm gonna begin by using what we call a self invoking anonymous function. And I don't want this to scare you. This isn't specific to jQuery. It's simply a JavaScript best practice. And here's the idea. If we're creating all of these variables: someVar, myVar, these are what we call global variables, which means they are available to the window object, window.myVar. And this is considered a bad practice, because you're muddying it up. You don't need to have all of these global variables. It's better to make those local variables so that they're not available to the global object. And this is generally what we do for simple projects, is you create a function. So, let's do this by hand, function. And then we want to execute that function immediately, because otherwise, it wouldn't run until you called it. So, I will wrap this function within parentheses, and then we're going to call it in the same way that you would call a normal func, using an opening and closing parentheses. So, I'll simply take that and pull it over, and now we have a function that immediately when the page loads will execute. And now, when I create a variable, it is local, and it's not available to the window object. So, get in the habit of doing that. Now, the first step is, we want to listen for when one of these buttons has clicked. And I'll show you a few different ways to do it. First, we'll take a look at the convenience version, and that's by using the click method. So, first, we need to target the button. So, I'm gonna say hey, jQuery, go into the DOM and fetch me all of the button elements. Note that that will not only refer to these, but if there are other ones from your page as well, it will return those, too. So, that's something you might wanna think about. Do they need to be within a container? Do they need to have a class so that you can target them? This will all depend on your specific project. But for now, I wanna keep it simple. So, jQuery, go get the buttons out of the DOM, and I want you to listen for when each is clicked on. So, we're going to use the click method. And then here, we need to pass a function. And this means what are we gonna do when this event happens? In this case, I'm going to pass an anonymous function. And this is fairly common. When something is clicked, run the contents of this function immediately. So, for now, just to make sure its working, we're going to console.log, button was clicked. All right, let's try this out. Reload the page. I'm gonna open up my console by using shift+command+c on the Mac, or by going to view, developer, developer tools. I'm gonna switch over to the console tab, and reload the page, and click a button. Button was clicked, good. So now, we need to figure out, how would I load a special style sheet? We now have that hook to know when we need to apply the style sheet, but how do we do that? Well, it's actually not too hard. Let's remove this code, and next I wanna demonstrate what this is. And this is something that is something that will confuse a lot of new jQuery developers. So, if I console.log this, what does this refer to? It's a key word, but what does it refer to? Well, I'll click on a button, and this is what we get. It refers to the element that was clicked. When working with jQuery, we grab something, wrap it in the jQuery object. We use one of these event helpers. And then, within the callback function, this will refer to the target. It will refer to the button that was clicked. So, if we use a different convenience method, perhaps hover, in that case, once again this will refer to the button that was hovered over. It's not going to refer to all of them. It's going to refer to the specific one. So, for example, if I click on day, this will refer to that one. If I click on night, this will refer to the night button. But now, at this point, this is not jQuery. So, I can't do this.click. I can't access any of those J query methods because we're simply referring to a regular dom node. If we want to gain access to jQuery's methods, we wrap it within jQuery once again. So, now if I come back, reload the page, click on it, you can see that now it's wrapped in jQuery, and we have access to all of the methods that we would normally have. For example, I can't do this.text changed, because text is a jQuery method. I try to do it, click on the button, we're going to get a type error. But this time, let's wrap in jQuery. That way we actually have access to it. Reload the page, click on it, and now can you see that we have updated it. So, that's an important distinction to make. Now next, I don't wanna get into this too much, but you might get into the habit of doing things where, you wrap it in jQuery, and then you do it again. And then maybe down here, you do something else. And you keep wrapping things in jQuery. And I don't want you to do this. I want you to think of the jQuery function like diving into a pool. So, every time you use this jQuery function, it is diving into the pool or what would actually be the DOM. And its figuring out what you need. Now, in this case, jQuery does have some optimizations. But, for example, if I'm doing jQuery ul, that's going to dive in to the dom, and return to me all of the unordered list wrapped in jQuery. And then, if a little later, I wanna do something else with that unordered list, and then a little bit later, I wanna do it again, this is what a lot of newcomers will do. They just keep referencing it. And so, when you do this you're essentially saying, hey, jQuery, jump into that pool three times. You don't wanna do that. Instead do as little amount of work as possible. So, what we would do instead is, we would jump into the dom that once. And we would return the results to a variable. And we could say var uls. And then you can use that, uls.click, uls.findl list item first child.text. You can use all of these methods. But now it's referring to the quote unquote ,cached version. This is something we often call caching. You're going to cache this query into a variable, and that way, we only jump into the pool a minimum number of times. But don't worry if that's still confusing. We're going to be covering these concepts more and more. All right, let me delete all of this and let's get started. Now, when the button is clicked, we want to first see if we can figure out how to replace the link. So, we'll hard code it in for now. I'm going to grab the link element. So, for now, let's be very generic, and then we'll improve upon our code as we go. Get the link element, wrap it in jQuery, and now I wanna update this href or href attribute. Now, we can use the adder method of the jQuery object .attr, attr. Now that refers obviously to attribute. Now, we can pass two parameters here. The first one is going to be the attribute that we want to modify. Or you can pass one, in which case, the value can be saved to a variable. And this is something that you can do often with jQuery. If you pass one attribute, you're returning the value. If you pass two, you're setting the value. Now, in our case, we want to set the value. So, link.adder. We're going to set the her ref attribute, and what are we going to set it to? I'm gonna hard code it in for now. Night.css, and let's see if that worked. Reload the page, click on night, and there we go. We've now updated the style sheet. If I go into the element tab, open up head, you can see that, yep, we've done it successfully. But, of course, it's not responding to the night button specifically, it's responding to any button. So, if I click on day, the same thing is going to occur. So now we need a way to specify, and you could maybe have many buttons here or you could have a list. We need a way to associate a button with the style sheet that it corresponds to. So, there's a couple ways. You can use the text of the button itself. I can say var style sheet is going to be this. And remember, this will refer to the button that was clicked. And we can say text. So, now if I log style sheet, reload the page, click on Day. That variable is now equal to day, and then we could maybe put a to lower case. This is a Javascript method. One more time. Click Day, and now we have the lowercase representation, and then I could simply say, link.adder her ref is going to equal stylesheet plus.css. Let's see how that works. Night, that works. Day, night. And that works. Now, is this the most ideal choice? Well, it depends. In this case, though, your text would always have to refer to the style sheet name, and that may not always be ideal. Another option you could do would be HTML5 custom attributes, and I could say data, file would equal day, and then we could do the same thing down here. So, as you'll learn, there's lots of different ways to, to solve a particular situation. it mostly depends on what's best for you. Now, in this case, when we're using custom attributes, we can access it a little bit differently. We can access the data attribute, and the way, if you're not familiar with these, in HTML5, you can use any number of custom attributes. I could do data-jeffrey, and that would be fine. The only requirement is it needs to be preceded with data dash. And that way, the browser knows that, hey, this is a custom attribute I'm dealing with. Now, to access that value with jQuery, once again, we could simply do attr data-file. That's one way we would do it. Let's view this in the browser one more time. Night, and we are getting that value. But jQuery has a better method we can use, and this is called the data method. Now traditionally, this is used to attach specific information to an element. So, I could get a ul and attach some unique bit of data. That way, in the future in my project, I can retrieve that data. But we can also use jQuery to access data attributes, and that makes sense, right? Now, the only difference is when you're using the data method, you don't do .data, data file. You cut off the prefix, because it's a little bit redundant. Now, let's try it, night, and, once again, we're getting that value. And that's one way we can refer to it. Now, let's begin optimizing this just a bit. Now, when the button is clicked, notice that every single time that button is clicked, we jump into the pool once again, and we grab a link element. Now, this isn't going to be a huge deal at all in our situation, but it's important for you to be thinking about these things. Why, every time the user clicks on a button, do you wanna jump into the dom? Why, when the user clicks on a button, do we want to jump into the dom every single time. Remember what we talked about before. Jump into the pool a minimal number of times. So, why don't we, at the top, create a variable called link, and make that to the link elements wrapped in the jQuery object? And that way, I'll remove this console.log, I can simply refer to that variable. And now, when that button is clicked, we're not jumping to the DOM every time. We're referencing this variable that is storing that reference. Let's try it again. Refresh. And now it's working just as it did before, but we're using best practices. Now, if you want to take this even further, if you think about it, every time this button is clicked, regardless of whether the current style sheet is equal to the value that is associated with the button, we're still executing this code. So, if you wanted, you can also detect, hey, is the current style sheet equal to what the user is clicking on. If so, I don't wanna do anything at all. Another option would be to disable the button that is currently selected, and that's what we're gonna do in this case. So, when a button is clicked, we are going to update the link attribute, and then at the bottom, we're going to say get this. But remember, once again, I'm now using two jQuery objects. So, I'm going to stash this, or cache it. And a very common thing, you'll, see is to use the word this, the keyword this, and prefix it with the dollar sign. Now, some people don't like this, but I think it works fine. And this is an easy way to let us know, hey, we actually have access to those jQuery methods in this variable. Now, I will replace it. This. And right here we're going to this.attribute disabled, and merely the presence of it will cause it to be disabled. But we can double up or set it to true. So one more time when click on night, you'll see that we received a night style sheet and now I can no longer click on that button. But now, as you might expect, when I click on day, the same thing happens, but we're not toggling these. So now, I can't click on any button at all. So, maybe when you click on a button, right here below, we can say get this. And now I wanna reference all of it's siblings. And this is a new method you're going to learn. Now, siblings refers to other elements on the same level. So, for example, if I had these stored within a div, and I said, button.siblings, it would refer to all other buttons on this level. However, it would not refer to any buttons that were on a different level or were part of an ancestor or descendant. So, that's an easy way. If you have the ability, and you know the DOM well enough, if you want to say, get all of the other buttons that are on this level, the siblings method will work well. And now, rather than setting an attribute or returning the value of an attribute, we wanna remove it entirely. So, now we use removeAttr. And we're going to remove the disabled attribute. Reload the page. I click on night. You can see that it is no longer selectable. But if I click on day, we're now toggling those. And now we don't have to worry about the user clicking on the day button more than once. Now, again, there's lots of different ways to do this. You could also detect whether the value of the link attribute is equal to this custom files value. You could do that, as well. And as long as they are not the same, then you make the update. Lots of different ways to do this. Now, the final thing is, right here, I'm going to update this value. And it's a best practice don't use multiple var statements. You can use a comma separated list. So, this is fairly common. You declare var once for the first variable, and then for every new one, you use a comma and you indent it like so. And it makes it a little bit cleaner. And the final step to clean up our code is I'll copy this, and I'm gonna make this occur first, and then we can group these together. So, we can sa,y get the button that was clicked. And then I want you to get its siblings, and I want you to remove any disabled attribute that may be applied to them. And then we can chain these. So, there's nothing wrong with using this twice, because we're not jumping into the DOM or the pool. We've already saved it. But if you wanna chain it, and it's not too long, we can group these together. But now it's important to remember that, at this point, if I were to try to do this, that would not work and the reason is, think about it. We're saying, get the button that was clicked, and now we're gonna change our selection to all other buttons, and then we're going to remove the attribute. And then we're going to apply an attribute. But we're applying an attribute to the siblings. We're no longer referencing the button that was clicked. So, in this case, we can use a helpful ends method. I'll indent these to show that these are associated with the siblings. And then, if I type .end, it's a way of saying, okay, we're done with that. Go back to where you were before. So, now we're done with the siblings. Go back to the jQuery object. And you could even do multiples of these. You just wanna be a little careful if it gets too convoluted. There's nothing wrong with separating them out. And now that we have our end method, we can take this out, and put it below. This does siblings button. Remove the attribute. We're done with siblings, so go back to the button that was clicked, and now we're going to disable the button itself. One more time, click on night. That's working. Day, and now I can no longer click on those. That works great. Now, the final step is, I'll close the semicolon out, is the click method is a helper. Now, these are convenience methods that jQuery makes available. There's also things like change, which wouldn't necessarily be applicable here, but you can match in when the user changes text in an input or they make a selection in a dropdown. There's also helpers like hover. Now, these will all translate to the on method. In translation, button.click is the same thing. It's going to point to button.on, click, function. It's the exact same thing. You'll find that I generally use this more direct route. And the reason is, button.click is simply another function that points to button.on,click, or the on method. So, why make it do more work calling additional methods when this is perfectly readable, as well? Get the buttons. When one of them is clicked, then do this. And the same thing. When one of them is hovered, or mouse enter, or you can refer to api.jquery.com for a full list, but don't worry we're gonna be covering a lot of them in this lesson. So, the final step is to make sure that it's still working. There it is, but now we're using the on method. But congratulations. This is your first little program. You could actually use this in your projects. And we're using jQuery, along with events.

Back to the top