MOBILE

jQuery 1.3 : Removing an event handler

8/21/2012 4:16:33 PM
There are times when we will be done with an event handler we previously registered. Perhaps the state of the page has changed such that the action no longer makes sense. It is typically possible to handle this situation with conditional statements inside our event handlers, but it may be more elegant to unbind the handler entirely.

Suppose that we want our collapsible style switcher to remain expanded whenever the page is not using the normal style. While the Narrow Column or Large Print button is selected, clicking the background of the style switcher should do nothing. We can accomplish this by calling the .unbind() method to remove the collapsing handler when one of the non-default style switcher buttons is clicked.

$(document).ready(function() {
$('#switcher').click(function(event) {
if (!$(event.target).is('.button')) {
$('#switcher .button').toggleClass('hidden');
}
});
$('#switcher-narrow, #switcher-large').click(function() {
$('#switcher').unbind('click');
});
});

Now when a button such as Narrow Column is clicked, the click handler on the style switcher <div> is removed, and clicking the background of the box no longer collapses it. However, the button doesn't work anymore! It is attached to the click event of the style switcher <div> as well because we rewrote the button-handling code to use event delegation. This means that when we call $('#switcher').unbind('click'), both behaviors are removed.

Event namespacing

We need to make our .unbind() call more specific, so that it does not remove both of the click handlers we have registered. One way of doing this is to use event namespacing. We can introduce additional information when an event is bound that allows us to identify that particular handler later. To use namespacing, we need to return to the non-shorthand method of binding event handlers, the .bind() method itself.

The first parameter we pass to .bind() is the name of the JavaScript event we want to watch for. We can use a special syntax here, though, that allows us to subcategorize the event.

$(document).ready(function() {
$('#switcher').bind('click.collapse', function(event) {
if (!$(event.target).is('.button')) {
$('#switcher .button').toggleClass('hidden');
}
});
$('#switcher-narrow, #switcher-large').click(function() {
$('#switcher').unbind('click.collapse');
});
});

The .collapse suffix is invisible to the event handling system; click events are handled by this function, just as if we wrote .bind('click'). However, the addition of the namespace means that we can unbind just this handler, without affecting the separate click handler we wrote for the buttons.

There are other ways of making our .unbind() call more specific, as we will see in a moment. However, event namespacing is a useful tool in our arsenal. 


Rebinding events

Now clicking the Narrow Column or Large Print button causes the style switcher collapsing functionality to be disabled. However, we want the behavior to return when the Default button is pressed. To do this, we will need to rebind the handler whenever Default is clicked.

First, we should give our handler function a name so that we can use it more than once without repeating ourselves:

$(document).ready(function() {
var toggleStyleSwitcher = function(event) {
if (!$(event.target).is('.button')) {
$('#switcher .button').toggleClass('hidden');
}
};
$('#switcher').bind('click.collapse', toggleStyleSwitcher);
});

Note that we are here using a new syntax for defining a function. Rather than defining the function by leading with the function keyword, we assign an anonymous function to a local variable. This is a stylistic choice to make our event handlers and other function definitions resemble each other more closely; the two syntaxes are functionally equivalent.

Also, recall that .bind() takes a function reference as its second argument. It is important to remember, when using a named function here, to omit parentheses after the function name; parentheses would cause the function to be called, rather than referenced.

Now that the function has a name, we can bind it again later without repeating the function definition:

$(document).ready(function() {
var toggleStyleSwitcher = function(event) {
if (!$(event.target).is('.button')) {
$('#switcher .button').toggleClass('hidden');
}
};
$('#switcher').bind('click.collapse', toggleStyleSwitcher);
$('#switcher-narrow, #switcher-large').click(function() {
$('#switcher').unbind('click.collapse');
});
$('#switcher-default').click(function() {
$('#switcher')
.bind('click.collapse', toggleStyleSwitcher);
});
});

Now the toggle behavior is bound when the document is loaded, unbound when Narrow Column or Large Print is clicked, and rebound when Normal is clicked after that.

We have sidestepped a potential pitfall here. Remember that when a handler is bound to an event in jQuery, previous handlers remain in effect. This would seem to mean that if Normal was clicked multiple times in succession, many copies of the toggleStyleSwitcher handler would be bound, causing strange behavior when the <div> was clicked. Indeed, if we had used anonymous functions throughout our example, this would be the case. But since we gave the function a name and used the same function throughout the code, the behavior is only bound once. The .bind() method will not attach an event handler to an element if it has already been attached.

As another benefit to naming this function, we no longer need to use namespacing. The .unbind() method can take a function as a second argument; in this case, it unbinds only that specific handler.

$(document).ready(function() {
var toggleStyleSwitcher = function(event) {
if (!$(event.target).is('.button')) {
$('#switcher .button').toggleClass('hidden');
}
};
$('#switcher').click(toggleStyleSwitcher);
$('#switcher-narrow, #switcher-large').click(function() {
$('#switcher').unbind('click', toggleStyleSwitcher);
});
$('#switcher-default').click(function() {
$('#switcher').click(toggleStyleSwitcher);
});
});

A shortcut is also available for the situation in which we want to unbind an event handler immediately after the first time it is triggered. This shortcut, called .one(), is used like this:

$(document).ready(function() {
$('#switcher').one('click', toggleStyleSwitcher);
});

This would cause the toggle action to occur only once.
Other  
 
Most View
The Review Of Three Seasonic Power Supply Suits (Part 2)
Sellerdeck Business 2013 – Great Ecommerce Software
Setting For Phones Using Windows Phone 8
Web Design: Where To Start (Part 1)
Windows Server 2008 and Windows Vista : GPMC Scripts - GPO Reporting (part 2)
Test Stereo Amplifiers - Driving Your Tunes Forward (Part 2) : Marantz PM6004, Onkyo A-9050
Windows Server 2008 R2 networking : Overview of Windows Server 2008 R2 Networking
ASRock Z77 Extreme3 LGA 1155 Mainboard - Simple, Reasonable And Extraordinary (Part 4)
Windows 8 : Managing Installed and Running Programs (part 2) - Managing the Command Path, Managing File Extensions and File Associations
How Secure Is Your Pin? (Part 1)
Top 10
Sharepoint 2013 : Farm Management - Disable a Timer Job,Start a Timer Job, Set the Schedule for a Timer Job
Sharepoint 2013 : Farm Management - Display Available Timer Jobs on the Farm, Get a Specific Timer Job, Enable a Timer Job
Sharepoint 2013 : Farm Management - Review Workflow Configuration Settings,Modify Workflow Configuration Settings
Sharepoint 2013 : Farm Management - Review SharePoint Designer Settings, Configure SharePoint Designer Settings
Sharepoint 2013 : Farm Management - Remove a Managed Path, Merge Log Files, End the Current Log File
SQL Server 2012 : Policy Based Management - Evaluating Policies
SQL Server 2012 : Defining Policies (part 3) - Creating Policies
SQL Server 2012 : Defining Policies (part 2) - Conditions
SQL Server 2012 : Defining Policies (part 1) - Management Facets
Microsoft Exchange Server 2010 : Configuring Anti-Spam and Message Filtering Options (part 4) - Preventing Internal Servers from Being Filtered