jQuery - A Crash Course for Beginners (Part 3 - Handling Events using jQuery)

This is part 3 of a 5 part series entitled jQuery - A Crash Course for Beginners. I highly suggest you start with Part 1 - An Introduction to jQuery if you are new to jQuery.

How Event Handlers Add Interaction to Your Site

How Event Handlers Add Interaction to Your SiteMost websites these days are pretty cut and dry. The only interaction that occurs is when a link is clicked or a form is submitted. On occasion you may see a navigation item change when the mouse "rolls over" it. The web doesn't have to be this boring though! In the past you had to jump through hoops to add more interaction to your website, but with jQuery, it's finally a piece of cake to handle actions associated with specific events. So, you may be asking yourself what events jQuery can handle. Here's a list of a few common events (most are pretty self-explanatory).

  • blur
  • focus
  • focusin
  • focusout
  • load
  • resize
  • scroll
  • unload
  • click
  • dblclick
  • mousedown
  • mouseup
  • mousemove
  • mouseover
  • mouseout
  • mouseenter
  • mouseleave
  • change
  • select
  • submit
  • keydown
  • keypress
  • keyup
  • error

One of my personal favorite features of jQuery is how easy it is to created event handlers. An event handler allows you to bind specific JavaScript or jQuery code to an event on an object. This code can then extend interaction and enhance the user experience. The best thing about creating an event handler in jQuery is the code remains unobtrusive – this means 100% of the code remains in your JavaScript file, and no further modifications need to be made to the HTML file.

To help us better understand how powerful event handlers can be, let's build out a real-world scenario. While creating a basic "roll-over" navigation is possible using only CSS and a :hover psuedo-selector, we're going to take it to the next level and not only use jQuery to handle our roll-overs, but we're going to do something special when users click a navigation item. This example is going to require 3 event handlers to accomplish what we want to do. We will create event handlers to handle the mouseenter, mouseleave, and click events. For those of you that are used to using the mouseover/mouseout events, here is a fantastic overview on why I prefer mouseenter/mouseleave instead.

The Basics of Binding

The Basics of BindingNo, we're not going to be tying anyone up (this isn't that kind of a website). We will however be tying some jQuery code to a specific element on our page. But first, let's build out our basic navigation. We're not going to worry about making this pretty, so a simple unordered list will suit us just fine.

<html>
   <head>
      <title>My Super Sweet Navigation</title>
   </head>
   <body>
   
   <ul id="navigation">
      <li><a href="home.html">Home</a></li>
      <li><a href="about.html">About</a></li>
      <li><a href="blog.html">Blog</a></li>
      <li><a href="contact.html">Contact</a></li>
   </ul>
   
   <div id="messageContainer"></div>
      
   <script src="jquery.min.js" type="text/javascript"></script>
   </body>
</html>

As you can see, I built a simple unordered list with an id of navigation, gave it 4 items (links), and added a div below it with an id of messageContainer. I'll explain more about that later. When creating event handlers, you want to bind to an element to intercept the actions made to it. There are several ways to do this. jQuery's .bind() method is my favorite approach, but you can also use shortcut methods as well. I'll show you how to use both. Let's just get right into our code and write our first event handler to cover the "roll-over" effect. The following code will be placed just after our jQuery include.

<script type="text/javascript">
   //Don't forget to make sure your DOM has fully loaded
   $(document).ready(function() {
   
      //Let's use jQuery's selector engine to find our navigation items. We'll search for the navigation id, select all list items (li) within that element, and finally all links (a) within those list items. The final result will be an array of links.
      var navItems = $("#navigation > li > a");
      
      //Now that we have traversed the document and found the links we were looking for, let's use the .bind() method to bind some jQuery code to the "mouseenter" and "mouseleave" events. We will chain these bind methods to the referrence to the links we found earlier. In the .bind() method, we specify an event name in quotes, and a callback function which after that event occurs, the code contained in the callback method will fire.   
      navItems.bind("mouseenter", function() {
         
         //$(this) represents a reference to the specific element that the event occured to. In this case it will reference one of the links in our navigation.
         $(this).css("font-weight","bold");
         
      }).bind("mouseleave", function() {
      
         //Now return it back to normal
         $(this).css("font-weight","normal");
         
      });
   });
</script>

Now, moving your mouse cursor over each link should fire the mouseenter binding, and turn the text bold. Upon leaving the link with your mouse, the text will return to normal font weight. As I said before, I'll show you how to use shortcut methods to save a few keystrokes. I'll also include a few other cool snippets.

//The cool thing about the mouseenter() shortcut method is that it also works to trigger the mouseenter event. More on that later.
navItems.mouseenter(function() {
   //$(this) represents a reference to the specific element that the event occured to. In this case it will reference one of the links in our navigation.
   $(this).css("font-weight","bold");
}).mouseleave(function() {
   $(this).css("font-weight","normal");
});

//You can also bind to multiple events. In this case both the mouseenter and click events will turn the text bold.

navItems.bind("mouseenter click", function() {
   $(this).css("font-weight","bold");
});

//We can pass the event object into our callback method to call specific information about the event that occurred.

navItems.bind("mouseenter", function(event) {
   //Log a message to the console containing the exact coordinates of the mouse cursor when it enters one of the links.
   console.log("The mouse cursor is at (" + event.pageX + ", " + event.pageY + ")");
});

Now that we've written our code to handle the mouseenter/mouseleave events, let's keep the ball rolling and jump right into the click event. This is going to be a little different because I want to actually intercept the click, and tell the browser to do something else (besides load value of the href attribute). To do this, we're going to pass the event object into our callback method, to stop the browser from doing what it typically does when links are clicked. Take a look:

<script type="text/javascript">
   //Don't forget to make sure your DOM has fully loaded
   $(document).ready(function() {
   
      //Let's use jQuery's selector engine to find our navigation items. We'll search for the navigation id, select all list items (li) within that element, and finally all links (a) within those list items. The final result will be an array of links.
      var navItems = $("#navigation > li > a");
      
      //Now that we have traversed the document and found the links we were looking for, let's use the .bind() method to bind some jQuery code to the "mouseenter" and "mouseleave" events. We will chain these bind methods to the referrence to the links we found earlier. In the .bind() method, we specify an event name in quotes, and a callback function which after that event occurs, the code contained in the callback method will fire.
      
      navItems.bind("mouseenter", function() {
         //$(this) represents a reference to the specific element that the event occured to. In this case it will reference one of the links in our navigation.
         $(this).css("font-weight","bold");
         
      }).bind("mouseleave", function() {
         
         //Now return it back to normal
         $(this).css("font-weight","normal");
         
      });
      
      //Bind the links to the click event, and pass in the event object
      navItems.bind("click", function(event) {
      
         //STOP the browser from loading the page specified in the link!
         event.preventDefault();
         
         //Now let's use our document traversing skills we've learned to find our what link we click, and where it wanted us to go.
         //Set the value of the link's description to a variable
         var linkName = $(this).html();
         
         //Now set the value of the link's location to another variable
         var linkLocation = $(this).attr("href");
         
         //Finally, let's modify that messageContainer we added to include a message about what just happened
         $("#messageContainer").html("You clicked the " + linkName + " link which should have taken you to " + linkLocation + ", but thanks to my event handler, I stopped that from happening so I could show you this sweet message!");
      });
   });
</script>

Your final result should turn the links bold when your mouse enters the element, and upon clicking each link, the messageContainer should update with a short message telling you what link you clicked and where that link would have taken you. This example is only the tip of the iceberg. I use the preventDefault() method to stop the browser from doing the default action so I can add rich interaction to the page. This is where AJAX or animations can come in handy, and we will most definitely cover those in the next few blog entries.

Triggering Events

Triggering events in jQuery is a beast of a topic, but I'll do my best to cover the basics of triggering and how useful it can be. There may be times when you need to manually trigger an event to fire that event handler. This can be useful to initialize your webpage or simply force code in an event handler to fire because of another even you're handling. Regardless, jQuery makes this extremely easy for you to do. Like most functions in jQuery, you can use the shortcut methods with no arguments passed in to manually trigger an event. Using the .trigger() method will execute the handlers in the same order they would be if the event were triggered naturally by the user. To trigger the event without causing the default behavior of an event (such as a form submission), use the .triggerHandler() method. Let's take a look at some examples.

//This will trigger the click event on the link. If any handlers were created to extend that functionality, they would also be fired.
   $("a").click();
   
   //The trigger() method works just like the shortcut method.
   $("a").trigger("click");
   
   //The triggerHandler() method will fire any event handlers that were written for this event WITHOUT performing the default browser functionality (which would be loading the value of the href attribute)
   $("a").triggerHandler("click");

For a more in-depth exploration, check out Ben Nadel's extensive exploration on the topic.

.Live() Binding to Future Elements

Before we conclude this blog entry, I wanted to discuss the .live() method and why it rocks so hard. Once you become more and more comfortable with creating event handlers using the .bind() or other various shortcut methods, you may find yourself in a scenario where you've used jQuery to add an element to your html page which should be bound as well, but for some reason it just isn't working. Confused? Let's build an example. In the following code, we have a button that when clicked will add paragraphs to a page. We want to also be able to click on each paragraph to delete them from the page. Two event handlers will have to be created, but the paragraph event handlers will be a little different. Take a look.

<html>
   <head>
      <title>My Super Sweet Navigation</title>
   </head>
   <body>
   
   <button type="button" class="addPara">Add Paragraph</button>   
   
   <div id="paraContainer"></div>
      
   <script src="jquery.min.js" type="text/javascript"></script>
   <script type="text/javascript">
      //Don't forget to make sure your DOM has fully loaded
      $(document).ready(function() {

         //Use the shortcut method to execute the code when the button containing the class addPara is clicked.
         $("button.addPara").click(function() {
            
            //Append a paragraph to the paraContainer element.
            $("#paraContainer").append("<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>");
         });
         
         //We're going to use the .live() method instead of .bind() because .bind() only applies to currently existing elements on the DOM - NOT elements that get created AFTER the DOM loads.
         $("p").live("click", function() {
         
            //Remove THIS paragraph
            $(this).remove();
            
         });
      });
   </script>
   </body>
</html>

If you tried using .bind(), or even .click() to create the event handler for removing the paragraph, you probably didn't have any luck with getting it to work. That's because those methods will only work on elements that exist at the time of that code being read by the browser. Since the paragraphs are added to our DOM after it loads, we need to use the .live() method to do the bindings. .live() will bind all current AND FUTURE elements. This especially comes in handy when you begin using AJAX on your site. For more information about .live(), see jQuery's API reference.

Conclusion

jQuery's simplistic approach to creating event handlers is not only extremely powerful, but also insanely easy. Intercepting events such as clicking on links, submitting forms, or even leaving a page, allows you as a developer to extend the default functionality to create a more rich and interactive user experience. To top everything off, gone are the days (FINALLY!) of needing to append onClick attributes to elements on your HTML page since jQuery allows for completely unobtrusive event handling using the .bind(), .live(), or equivalent shortcut methods.

4 responses to “jQuery - A Crash Course for Beginners (Part 3 - Handling Events using jQuery)”

  • tgpo
    Thanks for the easy explanation of the live binding. I noticed it surfacing more and more in scripts, but didn't fully comprehend what advantages it supplied.
  • Ryan Jeffords
    @tgpo The .live() binding is absolutely essential as you begin to become more advanced with jQuery and add/remove DOM elements dynamically. It makes your code much more compact and easy to write. jQuery 1.4 finally supports ALL event types as well so there's absolutely no reason to NOT use it.

    Enjoy my friend! :)
  • babak
    Thanks Ryan for a very clear and good introduction to JQ. When are you going to publish next parts?
  • Ryan Jeffords
    @babak Sorry for the delay on the last two sections. Work has kept me somewhat preoccupied. I'll see if I can squeeze them out in the near future. :)

    Thanks again for reading.

Leave a Reply

Leave this field empty:

Back to Top

Before you download my resume...

My Current Employment Status

I am currently happily employed and not actively seeking employment at this time. While I appreciate any and all interest in my skill-set, I am currently not available for a full-time hire. If you are interested in my skill-set and would like to hire me on a part-time basis, please contact me.

Contact Information

To avoid having my personal contact information floating freely through-out the internet, I have withheld my personal contact information from my resume. If you are interested in contacting me, please do so on my contact page.

Find Me, Follow Me, Friend Me!

Tags

Fellow Bloggers

Brought to you in part by

Epicenter Consulting - A Web Application Design and Strategy Firm