77
before it invokes the handler. It is sometimes useful to pass additional data to your
handlers in this way without having to use closures.
There are other advanced features of
bind()
as well. If the first argument is a space-
separated list of event types, then the handler function will be registered for each of the
named event types. The call
$('a').hover(f)
(see §19.4.1), for example, is the same as:
$('a').bind('mouseenter mouseleave', f);
Another important feature of
bind()
is that it allows you to specify a namespace (or
namespaces) for your event handlers when you register them. This allows you to define
groups of handlers and comes in handy if you later want to trigger or deregister the
handlers in a particular namespace. Handler namespaces are particularly useful for
programmers who are writing libraries or modules of reusable jQuery code. Event
namespaces look like CSS class selectors. To bind an event handler in a namespace,
add a period and the namespace name to the event type string:
// Bind f as a mouseover handler in namespace "myMod" to all <a> elements
$('a').bind('mouseover.myMod', f);
You can even assign a handler to multiple namespaces like this:
// Bind f as a mouseout handler in namespaces "myMod" and "yourMod"
$('a').bind('mouseout.myMod.yourMod', f);
The final feature of
bind()
is that the first argument can be an object that maps event
names to handler functions. To use the
hover()
method as an example again, the call
$('a').hover(f,g)
is the same as:
$('a').bind({mouseenter:f, mouseleave:g});
When you use this form of
bind()
, the property names in the object you pass can be
space-separated strings of event types and can include namespaces. If you specify a
second argument after the first object argument, that value is used as the data argument
for each of the event bindings.
jQuery has another event handler registration method. The
one()
method is invoked
and works just like
bind()
does, except that the event handler you register will auto-
matically deregister itself after it is invoked. This means, as the method name implies,
that event handlers registered with
one()
will never be triggered more than once.
One feature that
bind()
and
one()
do not have is the ability to register capturing event
handlers as you can with
addEventListener()
(§17.2.3). IE (until IE9) does not support
capturing handlers, and jQuery does not attempt to simulate that feature.
19.4.5 Deregistering Event Handlers
After registering an event handler with
bind()
(or with any of the simpler event regis-
tration methods), you can deregister it with
unbind()
to prevent it from being triggered
by future events. (Note that
unbind()
only deregisters event handlers registered with
bind()
and related jQuery methods. It does not deregister handlers passed to
addEventListener()
or the IE method
attachEvent()
, and it does not remove handlers
19.4 Handling Events with jQuery | 545
Client-Side
JavaScript
How to C#: Basic SDK Concept of XDoc.PDF for .NET XDoc.PDF for .NET allows C# developers to edit hyperlink of PDF document, including editing PDF url links and quick navigation link in bookmark/outline.
adding hyperlinks to pdf; add links to pdf document VB.NET PDF: Basic SDK Concept of XDoc.PDF XDoc.PDF for .NET allows VB.NET developers to edit hyperlink of PDF document, including editing PDF url links and quick navigation link in bookmark/outline.
pdf edit hyperlink; pdf link to specific page
63
defined by element attributes such as
onclick
and
onmouseover
.) With no arguments,
unbind()
deregisters all event handlers (for all event types) for all elements in the jQuery
object:
$('*').unbind(); // Remove all jQuery event handlers from all elements!
With one string argument, all handlers for the named event type (or types, if the string
names more than one) are unbound from all elements in the jQuery object:
// Unbind all mouseover and mouseout handlers on all <a> elements
$('a').unbind("mouseover mouseout");
This is a heavy-handed approach and should not be used in modular code because the
user of your module might be using other modules that register their own handlers for
the same event types on the same elements. If your module registered event handlers
using namespaces, however, you can use this one-argument version of
unbind()
to de-
register only the handlers in your namespace or namespaces:
// Unbind all mouseover and mouseout handlers in the "myMod" namespace
$('a').unbind("mouseover.myMod mouseout.myMod");
// Unbind handlers for any kind of event in the myMod namespace
$('a').unbind(".myMod");
// Unbind click handlers that are in both namespaces "ns1" and "ns2"
$('a').unbind("click.ns1.ns2");
If you want to be careful to unbind only event handlers you registered yourself and you
did not use namespaces, you must retain a reference to the event handler functions and
use the two-argument version of
unbind()
. In this form, the first argument is an event
type string (without namespaces) and the second argument is a handler function:
$('#mybutton').unbind('click', myClickHandler);
When invoked this way,
unbind()
deregisters the specified event handler function for
events of the specified type (or types) from all elements in the jQuery object. Note that
event handlers can be unbound using this two-argument version of
unbind()
even when
they were registered with an extra data value using the three-argument version of
bind()
.
You can also pass a single object argument to
unbind()
. In this case,
unbind()
is invoked
recursively for each property of the object. The property name is used as the event type
string and the property value is used as the handler function:
$('a').unbind({ // Remove specific mouseover and mouseout handlers
mouseover: mouseoverHandler,
mouseout: mouseoutHandler
});
Finally, there is one more way that
unbind()
can be invoked. If you pass a jQuery Event
object to it, it unbinds the event handler that that event was passed to. Calling
unbind(ev)
is equivalent to
unbind(ev.type, ev.handler)
.
546 | Chapter 19: The jQuery Library
76
19.4.6 Triggering Events
The event handlers you register are automatically invoked when the user uses the mouse
or keyboard or when other kinds of events occur. Sometimes, however, it is useful to
be able to manually trigger events. The simple way to do this is to invoke one of the
simple event registration methods (like
click()
or
mouseover()
) with no argument. Just
as many jQuery methods serve as both getters and setters, these event methods register
an event handler when invoked with an argument and trigger event handlers when
invoked with no arguments. For example:
$("#my_form").submit(); // Act as if the user clicked the Submit button
The
submit()
method in the line above synthesizes an Event object and triggers any
event handlers that have been registered for the submit event. If none of those event
handlers return
false
or call the
preventDefault()
method of the Event object, the form
will actually be submitted. Note that events that bubble will bubble even when triggered
manually like this. This means that triggering an event on a selected set of elements
may also trigger handlers on the ancestors of those elements.
It is important to note that jQuery’s event triggering methods will trigger any handlers
registered with jQuery’s event registration methods, and they will also trigger handlers
defined on HTML attributes or Element properties such as
onsubmit
. But you cannot
manually trigger event handlers registered with
addEventListener()
or
attachEvent()
(those handlers will still be invoked when a real event occurs, however).
Also note that jQuery’s event triggering mechanism is synchronous—there is no event
queue involved. When you trigger an event, event handlers are invoked immediately,
before the triggering method you called returns. If you trigger a click event and one of
the triggered handlers triggers a submit event, all of the matching submit handlers are
invoked before the next “click” handler is invoked.
Methods like
submit()
are convenient for binding and triggering events, but just as
jQuery defines a more general
bind()
method, so too it defines a more general
trigger()
method. Normally you invoke
trigger()
with an event type string as the first
argument and it triggers the handlers registered for events of that type on all elements
in the jQuery object. So the
submit()
call above is equivalent to:
$("#my_form").trigger("submit");
Unlike the
bind()
and
unbind()
methods, you cannot specify more than one event type
in this string. Like
bind()
and
unbind()
, however, you can specify event namespaces to
trigger only the handlers defined in that namespace. If you want to trigger only event
handlers that have no namespace, append an exclamation mark to the event type.
Handlers registered through properties like
onclick
are considered to have no
namespace:
$("button").trigger("click.ns1"); // Trigger click handlers in a namespace
$("button").trigger("click!"); // Trigger click handlers in no namespace
19.4 Handling Events with jQuery | 547
Client-Side
JavaScript
82
Instead of passing an event type string as the first argument to
trigger()
, you can also
pass an Event object (or any object that has a
type
property). The
type
property will be
used to determine what kind of handlers to trigger. If you specified a jQuery Event
object, that object will be the one passed to the triggered handlers. If you specified a
plain object, a new jQuery Event object will be created, and the properties of the object
you passed will be added to it. This is an easy way to pass additional data to event
handlers:
// The onclick handler of button1 triggers the same event on button2
$('#button1').click(function(e) { $('#button2').trigger(e); });
// Add an extra property to the event object when triggering an event
$('#button1').trigger({type:'click', synthetic:true});
// This handler tests that extra property to distinguish real from synthetic
$('#button1').click(function(e) { if (e.synthetic) {...}; });
Another way to pass additional data to event handlers when you trigger them manually
is to use the second argument to
trigger()
. The value you pass as the second argument
to
trigger()
will become the second argument to each of the event handlers that is
triggered. If you pass an array as the second argument, each of its elements will be
passed as arguments to the triggered handlers:
$('#button1').trigger("click", true); // Pass a single extra argument
$('#button1').trigger("click", [x,y,z]); // Pass three extra arguments
Sometimes you may want to trigger all handlers for a given event type, regardless of
which document element those handlers are bound to. You could select all elements
with
$('*')
and then call
trigger()
on the result, but that would be very inefficient.
Instead, to trigger an event globally, call the
jQuery.event.trigger()
utility function.
This function takes the same arguments as the
trigger()
method and efficiently triggers
event handlers for the specified event type throughout the document. Note that “global
events” triggered in this way do not bubble, and only handlers registered using jQuery
methods (not event handlers registered with DOM properties like
onclick
) are triggered
with this technique.
After invoking event handlers,
trigger()
(and the convenience methods that call it)
perform whatever default action is associated with the triggered event (assuming that
the event handlers didn’t return false or call
preventDefault()
on the event object). For
example, if you trigger a submit event on a
<form>
element,
trigger()
will call the
submit()
method of that form, and if you trigger a focus event on an element,
trigger()
will call the
focus()
method of that element.
If you want to invoke event handlers without performing the default action, use
triggerHandler()
instead of
trigger()
. This method works just like
trigger()
, except
that it first calls the
preventDefault()
and
cancelBubble()
methods of the Event object.
This means that the synthetic event does not bubble or perform the default action
associated with it.
548 | Chapter 19: The jQuery Library
78
19.4.7 Custom Events
jQuery’s event management system is designed around the standard events like mouse
clicks and key presses that web browsers generate. But it is not tied to those events,
and you can use any string you want as an event type name. With
bind()
you can register
handlers for this kind of “custom event” and with
trigger()
you can cause those han-
dlers to be invoked.
This kind of indirect invocation of custom event handlers turns out to be quite useful
for writing modular code and implementing a publish/subscribe model or the Observer
pattern. Often when using custom events you may find it useful to trigger them globally
with the
jQuery.event.trigger()
function instead of the
trigger()
method:
// When the user clicks the "logoff" button, broadcast a custom event
// to any interested observers that need to save their state and then
// navigate to the logoff page.
$("#logoff").click(function() {
$.event.trigger("logoff"); // Broadcast an event
window.location = "logoff.php"; // Navigate to a new page
});
We’ll see in §19.6.4 that jQuery’s Ajax methods broadcast custom events like this to
notify interested listeners.
19.4.8 Live Events
The
bind()
method binds event handlers to specific document elements just as
addEventListener()
and
attachEvent()
(see Chapter 17) do. But web applications that
use jQuery often dynamically create new elements. If we’ve used
bind()
to bind an
event handler to all
<a>
elements in the document and then we create new document
content with new
<a>
elements, those new elements will not have the same event han-
dlers as the old ones and will not behave in the same way.
jQuery addresses this issue with “live events.” To use live events, use the
delegate()
and
undelegate()
methods instead of
bind()
and
unbind()
.
delegate()
is usually in-
voked on
$(document)
and is passed a jQuery selector string, a jQuery event type string,
and a jQuery event handler function. It registers an internal handler on the document
or window (or on whatever elements are in the jQuery object). When an event of the
specified type bubbles up to this internal handler, it determines whether the target of
the event (the element that the event occurred on) matches the selector string. If so, it
invokes the specified handler function. So to handle mouseover events on both old and
newly created
<a>
elements, you might register a handler like this:
$(document).delegate("a", "mouseover", linkHandler);
Or you might use
bind()
in the static portions of your document and then use
delegate()
to handle the portions that change dynamically:
// Static event handlers for static links
$("a").bind("mouseover", linkHandler);
19.4 Handling Events with jQuery | 549
Client-Side
JavaScript
81
// Live event handlers for parts of the document that are dynamically updated
$(".dynamic").delegate("a", "mouseover", linkHandler);
Just as the
bind()
method has a three-argument version that allows you to specify the
value of the
data
property of the event object, the
delegate()
method has a four-
argument version that allows the same thing. To use this version, pass the data value
as the third argument and the handler function as the fourth.
It is important to understand that live events depend on event bubbling. By the time
an event bubbles up to the document object, it may have already been passed to a
number of static event handlers. And if any of those handlers called the
cancelBubble()
method of the Event object, the live event handler will never be invoked.
jQuery defines a method named
live()
that can also be used to register live events.
live()
is a little harder to understand than
delegate()
, but it has the same two- or three-
argument signature as
bind()
and is more commonly used in practice. The two calls to
delegate()
shown above could also be written as follows using
live()
:
$("a").live("mouseover", linkHandler);
$("a", $(".dynamic")).live("mouseover", linkHandler);
When the
live()
method is invoked on a jQuery object, the elements in that object are
not actually used. What matters instead is the selector string and the context object
(the first and second arguments to
$()
) that were used to create the jQuery object.
jQuery objects make these values available through their
context
and
selector
prop-
erties (see §19.1.2). Normally, you invoke
$()
with only one argument and the context
is the current document. So for a jQuery object
x
, the following two lines of code do
the same thing:
x.live(type,handler);
$(x.context).delegate(x.selector, type, handler);
To deregister live event handlers, use
die()
or
undelegate()
.
die()
can be invoked with
one or two arguments. With one event type argument, it removes all live event handlers
that match the selector and the event type. And with an event type and handler function
argument, it removes only the one specified handler. Some examples:
$('a').die('mouseover'); // Remove all live handlers for mouseover on <a> elts
$('a').die('mouseover', linkHandler); // Remove just one specific live handler
undelegate()
is like
die()
but more explicitly separates the context (the elements on
which the internal event handlers are registered) and the selector string. The calls to
die()
above could instead be written like this:
$(document).undelegate('a'); // Remove all live handlers for <a> elements
$(document).undelegate('a', 'mouseover'); // Remove live mouseover handlers
$(document).undelegate('a', 'mouseover', linkHandler); // One specific handler
Finally,
undelegate()
can also be called with no arguments at all. In this case, it dereg-
isters all live event handlers that are delegated from the selected elements.
550 | Chapter 19: The jQuery Library
60
19.5 Animated Effects
Chapter 16 showed how to script the CSS styles of document elements. By setting the
CSS
visibility
property, for example, you can make elements appear and disappear.
§16.3.1 went on to demonstrate how CSS scripting can be used to produce animated
visual effects. Instead of just making an element disappear, for example, we might
reduce the value of its
opacity
property over the period of a half second so that it quickly
fades away instead of just blinking out of existence. This kind of animated visual effect
creates a more pleasing experience for users, and jQuery makes them easy.
jQuery defines simple methods such as
fadeIn()
and
fadeOut()
for basic visual effects.
In addition to simple effects methods, it defines an
animate()
method for producing
more complex custom animations. The subsections below explain both the simple
effects methods and the more general
animate()
method. First, however, we’ll describe
some general features of jQuery’s animation framework.
Every animation has a duration that specifies how long the effect should last for. You
specify this as a number of milliseconds or by using a string. The string “fast” means
200ms. The string “slow” means 600ms. If you specify a duration string that jQuery
does not recognize, you’ll get a default duration of 400ms. You can define new duration
names by adding new string-to-number mappings to
jQuery.fx.speeds
:
jQuery.fx.speeds["medium-fast"] = 300;
jQuery.fx.speeds["medium-slow"] = 500;
jQuery’s effect methods usually take effect duration as an optional first argument. If
you omit the duration argument, you usually get the default 400ms. Some methods,
however, produce an instant nonanimated effect when you omit the duration:
$("#message").fadeIn(); // Fade an element in over 400ms
$("#message").fadeOut("fast"); // Fade it out over 200ms
Disabling Animations
Animated visual effects have become the norm on many websites, but not all users like
them: some users find them distracting and others feel they cause motion sickness.
Disabled users may find that animations interfere with assistive technology like screen
readers and users on old hardware may feel that they require too much processing
power. As a courtesy to your users, you should generally keep your animations simple
and understated and also provide an option to disable them completely. jQuery makes
it easy to globally disable all effects: simply set
jQuery.fx.off
to
true
. This has the effect
of changing the duration of every animation to 0ms, making them behave as instanta-
neous, nonanimated changes.
To allow end users to disable effects, you might use code like this in your scripts:
$(".stopmoving").click(function() { jQuery.fx.off = true; });
Then, if the web designer includes an element with class “stopmoving” on the page,
the user can click it to disable animations.
19.5 Animated Effects | 551
Client-Side
JavaScript
58
jQuery’s effects are asynchronous. When you call an animation method like
fadeIn()
, it returns right away and the animation is performed “in the background.”
Because animation methods return before the animation is complete, the second ar-
gument (also optional) to many of jQuery’s effect methods is a function that will be
invoked when the effect is complete. The function is not passed any arguments, but
the
this
value is set to the document element that was animated. The callback function
is invoked once for each selected element:
// Quickly fade in an element, and when it is visible, display some text in it.
$("#message").fadeIn("fast", function() { $(this).text("Hello World"); });
Passing a callback function to an effect method allows you to perform actions at the
end of an effect. Note, however, that this is not necessary when you simply want to
perform multiple effects in sequence. By default, jQuery’s animations are queued
(§19.5.2.2 shows how to override this default). If you call an animation method on an
element that is already being animated, the new animation does not begin right away
but is deferred until the current animation ends. For example, you can make an element
blink before fading in permanently:
$("#blinker").fadeIn(100).fadeOut(100).fadeIn(100).fadeOut(100).fadeIn();
jQuery’s effect methods are declared to accept optional duration and callback argu-
ments. It is also possible to invoke these methods with an object whose properties
specify animation options:
// Pass duration and callback as object properties instead of arguments
$("#message").fadeIn({
duration: "fast",
complete: function() { $(this).text("Hello World"); }
});
Passing an object of animation objects is most commonly done with the general
animate()
method, but it is also possible for the simpler effects methods. Using an
options object allows you to set other advanced options to control queuing and easing,
for example. The available options are explained in §19.5.2.2.
19.5.1 Simple Effects
jQuery defines nine simple effects methods to hide and show elements. They can be
divided into three groups based on the kind of effect they perform:
fadeIn()
,
fadeOut()
,
fadeTo()
These are the simplest effects:
fadeIn()
and
fadeOut()
simply animate the CSS
opacity
property to show or hide an element. Both accept optional duration and
callback arguments.
fadeTo()
is slightly different: it expects a target opacity argu-
ment and animates the change from the element’s current opacity to this target.
For the
fadeTo()
method, the duration (or options object) is required as the first
argument and the target opacity is required as the second argument. The callback
function is an optional third argument.
552 | Chapter 19: The jQuery Library
Documents you may be interested
Documents you may be interested