Removing event handlers

Typically, once an event handler is established using on(), it remains in effect for the remainder of the life of the page. But particular interactions may dictate that handlers be removed based on certain criteria. Consider, for example, a page where multiple steps are presented and once a step has been completed, its controls revert to read-only.

For such cases, it would be advantageous to remove event handlers under script control to save memory. You’ve seen that the one() method can automatically remove a handler after it has completed its first (and only) execution, but for the more general cases where you’d like to remove event handlers under your own control, jQuery provides an on() counterpart called off(). The syntax of off(), shown next, has parameters with the same meaning described for on() and one(), so we won’t repeat them.

Method syntax: off
off(eventType[, selector][, handler]) off(eventsHash, [, selector]) off()
Removes event handlers from all elements of the jQuery object as specified by the optional parameters given. If no parameters are provided, all listeners are removed from the elements.
Returns
The jQuery collection.

You can use this method to remove event handlers from the elements of the jQuery object at various levels of granularity. All listeners can be removed by omitting all the parameters. Listeners of a specific type can be removed by providing just that event type. If the name of one or more events is provided, all the handlers are removed, delegated or not. Finally, specific handlers can be removed by providing a reference to the function originally established as the listener. To do this, a reference to the function must be retained when binding the function as an event listener in the first place. For this reason, when a function that’s eventually to be removed as a handler is originally established as a listener, it’s either defined as a top-level function (so that it can be referred to by its top-level variable name) or a reference to it is retained by some other means. Supplying the function as an anonymous inline reference would make it impossible to later reference the function in a call to off().

jQuery 3: Methods deprecated

The off() method provides a unified interface to replace unbind()undelegated(), and die() (what a scary name!). Like their respective counterparts, die() (a counterpart of live()) was deprecated in version 1.7 and then removed in version 1.9, whereas unbind() (a counterpart of bind()) and undelegate() (a counterpart of delegate()) were still in the core but their use was discouraged. jQuery 3 deprecates the unbind() and undelegate() methods, so we suggest you stick with off().

In the case of anonymous inline functions, using namespaced events can come in quite handy, because you can unbind all events in a particular namespace without having to retain individual references to the listeners. For example,

$('*').off('.fred');

will remove all event listeners in namespace fred (remember that in this case the period in front of the name doesn’t indicate a class selector). This use of namespaces is particularly useful when attaching handlers from a jQuery plugin, as we’ll discuss in lesson 12.

Before moving on, let’s see an example of using on() and off(). Consider the following markup where you have three buttons:

<button id="btn">Does nothing</button>
<button id="btn-attach">Attach handler</button>
<button id="btn-remove">Remove handler</button>

Moreover, you have the following code:

The idea is to have the first button, which does nothing by its own, and the other two buttons, which attach a handler to the first button and remove the handler, respectively. Inside the handler, you print on the console the number of times the button was clicked while the handler was attached .

To perform this task, in the first part of the code you declare a variable, $btn, containing a set made of one element, the first button (the one having btn as its ID). Then you declare the counter (counter) and a function that you’ll use later as the handler on the button. In the second part of the snippet, you attach an inline handler to the second button (the one having btn-attach as its ID), using the on() method . Its aim is to attach the function logHandler as a handler of the first button when the click event is fired. In the same way, you attach an inline handler to the third button (the one having btn-remove as its ID) whose aim is to remove the handler from the first button . You can see this example in action in the file lesson-6/adding .removing.handlers.html and also as a JS Bin. Note that multiple clicks of the Attach handler button will add a number of identical event handlers, so the counter will jump accordingly at every click of the Log button.

So far, you’ve seen that the jQuery Event Model makes it easy to establish (as well as remove) event handlers without worrying about browser differences, but what about writing the event handlers themselves?

6.2.3. Inspecting the Event instance

When an event handler established with the on() method or the other ones we’ve mentioned is invoked, an Event instance is passed to it as the first parameter to the function regardless of the browser, eliminating the need to worry about the window.event property under older versions of Internet Explorer. But that still leaves you dealing with the divergent properties of the Event instance, doesn’t it?

Thankfully, no, because jQuery doesn’t really pass the Event instance to the handlers. Screech! (sound of a needle being dragged across a record).

Yes, we’ve been glossing over this little detail because, up until now, it hasn’t mattered. But now that we’ve advanced to the point where we’re going to examine the instance within handlers, the truth must be told!

In reality, jQuery defines an object of type jQuery.Event that it passes to the handlers. But you can forgive us for our simplification because jQuery copies most of the original Event properties to this object. Therefore, if you look for only the properties that you expected to find on Event, the object is almost indistinguishable from the original Event instance.

But that’s not the important aspect of this object; what’s really valuable, and the reason that this object exists, is that it holds a set of normalized values and methods that you can use independently of the containing browser, ignoring the differences in the Event instance.

Table 6.2 lists the jQuery.Event properties that are safe to access in a platform-independent manner. Note that some properties may have the value undefined depending on the event triggered.

Table 6.2. Browser-independent jQuery.Event properties
Properties
altKey
bubbles
button
cancelable
charCode
clientX
clientY
ctrlKey
currentTarget
data
detail
delegateTarget
eventPhase
metaKey*
namespace
offsetX
offsetY
originalTarget
originalEvent
pageX*
pageY*
prevValue
relatedTarget*
result
screenX
screenY
shiftKey
target*
timeStamp
type
view
which*

As you can see, some of the properties have been marked with an asterisk. The reason is that jQuery normalizes them for cross-browser consistency. What this means is that they’re named differently in some browsers (yes, older versions of Internet Explorer). To avoid the pain of remembering all these differences, jQuery provides one property name and takes care of filling the holes. One example is the target property, which in older versions of Internet Explorer is called srcElement. In addition, some events may have specific properties that you can access through the originalEvent property.

The jQuery.Event object also has several methods, described in table 6.3.

Table 6.3. Browser-independent jQuery.Event methods
Methods
preventDefault()Prevents any default semantic action (such as form submission, link redirection, check box state change, and so on) from occurring.
stopPropagation()Stops any further propagation of the event up the DOM tree. Additional events on the current target aren’t affected. Works with browser-defined events as well as custom events.
stopImmediatePropagation()Stops all further event propagation including additional events on the current target.
isDefaultPrevented()Returns true if the preventDefault() method has been called on this instance.
isPropagationStopped()Returns true if the stopPropagation() method has been called on this instance.
isImmediatePropagationStopped()Returns true if the stopImmediatePropagation() method has been called on this instance.

In addition to allowing you to manage event handling and the Event object in a browser-independent manner, jQuery provides a set of methods that gives you the ability to trigger events or run event handlers under script control. Let’s look at those.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *