dcsimg

Dynamically Adding and Removing Event Handlers with jQuery

By Rob Gravelle

WEBINAR:
On-Demand

Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame


Once upon a time, event handlers were bound to HTML elements using an inline "on[action]" attribute. It was not a great implementation for several reasons. First, it was not dynamic. It was also limited to one and only one handler. Yuck! Today, we can bind numerous handlers to the same element event at any time. Moreover, we can remove said handlers at will. Why would you want to do that? There may be a variety of reasons, form dynamic elements to efficient use of resources. In today's blog, we'll learn how to easily bind and remove event handlers using a little jQuery.

Adding an Event Handler

In earlier versions of jQuery, the $.fn.bind() method was employed; it has since been deprecated (as of jQuery version 1.7) in favor of $.fn.on(). The on() method is not limited to form controls like buttons and inputs; it can even attach handlers to paragraphs!

$("h1,p,a").on( "click", function() {
  alert("You clicked an element.");
});

As great as the on() method is, you'll probably find yourself rarely using it, because most events have their own method. For instance, the click() method assigns a handler to click events. Other methods include blur(), change(), contextmenu() and dblclick(). You can invoke these on any one element or collection of elements:

$("h1,p,a").click(function(e) {
  alert("You clicked a "+e.target.tagName+" element.");
});

The aforementioned event binding methods will work for all matching elements at the time that the binding event is invoked. Hence, elements that are added later will not trigger the bound event handlers.

To illustrate, here is some code that appends a new paragraph element at the bottom of the page whenever a button is pressed:

$("#add-element").click(function(e) {
  // this stops the event from bubbling up to the P element
  e.stopPropagation();
  $("body").append($("<P>").text("This is a dynamic paragraph."));
});

Clicking on one of those paragraphs will do nothing.

So, what's to be done? Another version of the on() and shortcut methods may be employed to bind a handler on matching elements, whether already present or dynamically added later:

$(document).click("h1,p,a", function() {
  alert("This handler is invoked by existing and new elements!");
});

Removing Event Handlers

Sometimes you need a way to dynamically unbind an event handler from an element, for example, when a user enters a value such as zero (0) into a text box. There are a few ways to do it, as shown below.

One-time Event Binding

You can employ the .one() method if you only want to invoke your handler once. Hence, it's identical to .on(), except that the handler for each matching element and event type is unbound after its first invocation. For example:

$("h1,p,a").one("click", function(e) {
  alert("This handler will only execute once.");
});

The .off() Method

Event handlers that were attached with .on() can be removed using its .off() counterpart method. There are a couple of ways to call it:

  1. Calling .off() with no arguments removes ALL handlers attached to the elements.
  2. You can also remove specific event handlers by providing combinations of event names, selectors, and/or handler function names. When multiple filtering arguments are given, as we did in the above examples, all of the arguments provided must be provided to the off() method for the event handler to be removed.

Direct vs. Delegated Event Handlers

This would probably be a good point to outline the difference between direct and delegated events. As you may be aware, the majority of browser events bubble, or propagate, from the deepest, innermost element (the event target) all the way up to the body and document elements. In order to remove event handlers, you need to know which type of event you're dealing with.

If selector is omitted or is null, the event handler is referred to as direct or directly-bound. Thus, the handler is called every time an event occurs on the selected elements, whether it occurs directly on the element or bubbles from a descendant (inner) element. The following code would remove the original event handler (the one that only fires on existing elements:

$("h1,p,a").off("click");

By providing a selector you can target the delegated event handlers. In that case, the handler is not called when the event occurs directly on the bound element, but only for its descendants that match the selector. JQuery bubbles the event from the event target up to the element where the handler is attached from the innermost to outermost element and runs the handler for any elements along that path matching the selector.

Conclusion

jQuery makes it fairly easy to bind and remove event handlers either when the page loads, or at runtime. If you'd like to see today's code in action, it's up on Codepen.



Rob Gravelle

Rob Gravelle resides in Ottawa, Canada. His design company has built web applications for numerous businesses and government agencies. Email him.

Rob's alter-ego, "Blackjacques", is an accomplished guitar player, who has released several CDs and cover songs. His band, Ivory Knight, was rated as one of Canada's top hard rock and metal groups by Brave Words magazine (issue #92).



  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
  •  
  •  
  •  
Thanks for your registration, follow us on our social networks to keep up-to-date