Most of jQuery's event-handling methods correspond
directly to native JavaScript events. A handful, however, are custom
handlers added for convenience and cross-browser optimization. One of
these, the .ready() method, we have discussed in detail already. The .toggle() and .hover() methods are two more custom event handlers; they are both referred to as compound event handlers because they intercept combinations of user actions, and respond to them using more than one function.
Showing and hiding advanced features
Suppose that we wanted to be able
to hide our style switcher when it is not needed. One convenient way to
hide advanced features is to make them collapsible. We will allow one
click on the label to hide the buttons, leaving the label alone. Another
click on the label will restore the buttons. We need another class to
handle the hidden buttons:
.hidden {
display: none;
}
We could implement this
feature by storing the current state of the buttons in a variable, and
checking its value each time the label is clicked to know whether to add
or remove the hidden class on the
buttons. We could also directly check for the presence of the class on a
button, and use this information to decide what to do. Instead, jQuery
provides the .toggle() method, which performs this housekeeping task for us.
There are in fact two .toggle() methods defined by jQuery. For information on the effect method of this name (which is distinguished by different argument types), see: http://docs.jquery.com/Effects/toggle
The .toggle()
event method takes two or more arguments, each of which is a function.
The first click on the element causes the first function to execute, the
second click triggers the second function, and so forth. Once each
function has been invoked, the cycle begins again from the first
function. With .toggle(), we can implement our collapsible style switcher quite easily:
$(document).ready(function() {
$('#switcher h3').toggle(function() {
$('#switcher .button').addClass('hidden');
}, function() {
$('#switcher .button').removeClass('hidden');
});
});
After the first click, the buttons are all hidden:
And a second click returns them to visibility:
Once again we rely on implicit
iteration; this time, to hide all the buttons in one fell swoop without
requiring an enclosing element.
For this specific case, jQuery provides another mechanism for the collapsing we are performing. We can use the .toggleClass() method to automatically check for the presence of the class before applying or removing it:
$(document).ready(function() {
$('#switcher h3').click(function() {
$('#switcher .button').toggleClass('hidden');
});
});
In this case, .toggleClass() is probably the more elegant solution, but .toggle() is a more versatile way to perform two or more different actions in alternation.
Highlighting clickable items
In illustrating the ability of the click
event to operate on normally non-clickable page elements, we have
crafted an interface that gives few hints that the buttons—actually just
<div> elements—are actually live
parts of the page, awaiting user interaction. To remedy this, we can
give the buttons a rollover state, making it clear that they interact in
some way with the mouse:
#switcher .hover {
cursor: pointer;
background-color: #afa;
}
The CSS specification includes a pseudo-class called :hover,
which allows a stylesheet to affect an element's appearance when the
user's mouse cursor hovers over it. In Internet Explorer 6, this
capability is restricted to link elements, so we can't use it for other
items in cross-browser code. Instead, jQuery allows us to use JavaScript
to change an element's styling—and indeed, perform any arbitrary
action—both when the mouse cursor enters the element and when it leaves
the element.
The .hover() method takes two function arguments, just as in our .toggle()
example above. In this case, the first function will be executed when
the mouse cursor enters the selected element, and the second is fired
when the cursor leaves. We can modify the classes applied to the buttons
at these times to achieve a rollover effect:
$(document).ready(function() {
$('#switcher .button').hover(function() {
$(this).addClass('hover');
}, function() {
$(this).removeClass('hover');
});
});
We once again use implicit
iteration and event context for short, simple code. Now when hovering
over any button, we see our class applied as shown in the following
screenshot:
The use of .hover() also means we avoid headaches caused by event propagation in JavaScript. To understand this, we need to take a look at how JavaScript decides which element gets to handle a given event.