Dynamic event handlers
Dynamic event handlers
Chances are, when you're creating event handlers, you'll use the function that matches the event the vast majority of the time. After all, it's straight forward to type out, and later read,
$('selector').click(function() {});
when you're comfortable with jQuery. But this approach does have only drawback: the only event you're going to register with that syntax is click
. What happens if you want to be able to register the same event handler for multiple events? Or what about a scenario where you need to determine the event based on something else that happens on the screen - maybe changing mouseenter
to click
?
With
on
and off
, you can register and unregister event handlers, respectively, while passing in the name of the event, or events, as a string.on and off
Both
on
and off
share the same syntax:$('selector').('events', 'selector (optional)', function)
events
: A space separated list of the events you wish to register, such as'click'
or'click mouseenter'
selector (optional)
: An optional selector. We will discuss this in the next unitfunction
: The function you wish to call. As per usual, this can be either a regular function or, typically, an anonymous function.
// the following two code blocks are semantically the same
$('#demo').on('click', function() { alert('hello!!'); });
$('#demo').click(function() { alert('hello!!'); });
Which should you use?
Often the choice between using
click(function() {})
or on('click', function() {})
is a matter of personal preference. For me I'll use the function click
, or whichever one matches the event, whenever possible. This is both because of the Intellisense offered in Visual Studio (or other auto-complete technology in other editors) and readability. Obviously if you need to dynamically choose the event, or if you need multiple events for the same event handler, using on
is your only choice. In additon, on
offers one more feature, known as delegation, which we'll explore on the next page.Delegation
Delegation and dynamic elements
One of the concepts we'll explore later is power jQuery offers developers for modifying the DOM programatically. You can easily add buttons, div elements, etc., as needed.
The question then becomes, what would happen in the following scenario?
<button>Click</button>
<div id="placeholder"></div>
$(function() {
// document.ready (on load)
// register a click event handler with all button elements
$('button').click(function() { alert('hello'); });
// create a new button
$('#placeholder').html('<button>New button</button>');
});
When the JavaScript code executes, a new button will be created after we registered an event handler for all buttons. Does the new button get the same
click
event handler?Introducing delegate
In order for
click
, or, in some cases, on
, to work, the element must already be on the page. As a result, if you registered an event handler, and then later created a new element that would match the selector you used, the event handler wouldn't apply.
Enter
delegate
. Registering an event handler using delegate
, as demonstrated above, is similar to on
, with one major difference: New elements will automatically have the event handler applied.
Using the above example, if we updated the
click
event handler registration to the new code below, both the existing button and new button would have the same event handler.$(document).delegate('button', 'click', function() { alert('hello'); });
The
delegate
syntax is $(selector).delegate(selector, events, eventHandler)
$(selector)
: In order to usedelegate
, the jQuery factory must return a parent of the object you wish to wire up.selector
: From the parent, provide a selector to retrieve the necessary elements.events
: Same events string as before.eventHandler
: Same event handler as before.
One important note about using
delegate
is you are required to start at a parent object, rather than at the object itself. For example, in the scenario proposed above, we want to register the same click
event handler for all buttons. Normally the selector would be 'button'
. But, delegate
requires we start at a parent, and then the selector
we provide as the first parameter will locate the elements from that parent. Since we want all buttons, we can use document
, which will give us the entire document.Delegating event handlers with on
With jQuery 1.7,
delegate
is superseded by on
. You may have noticed in the prior unit on
had a selector parameter as well. If you do not provide that selector, on
behaves like a normal event handler registration. But, if you do provide a selector, it will use delegation to register the event handlers.
One important thing to note is the order of parameters for
on
and delegate
. With on
, you list the events first and the selector second. With delegate
, it's selector followed by events.// Delegation (note the order of parameters)
$(document).on('click', 'button', function() {alert('hello'); });
// Semantically the same as above
// (note the order of parameters)
$(document).delegate('button', 'click', function() { alert('hello'); });
Single execution
Single execution
When you register an event handler with an object, that event handler will remain with that object until you unregister it, which you could do with a function such as
off
.
However, what if you know in advance you only want the event to execute once? For instance, if you're creating a button that will submit a form, you only want the user to click the button once. Wouldn't it be great if you could tell jQuery to only use the event handler one time?
Fortunately, you can!
one
one
shares a similar syntax with on
, only there is no delegation option. You simply provide the name of the event, and the event handler.<button id="single">This only works once</button>
<div id="output"></div>
$(function() {
$('#single').one('click', function() {
$('#output').text('You clicked on the button');
});
});
(note: while there is an overload of
one
that allows for a selector, it will only filter which children the event applies to. It will not enable delegation.)Triggering events
Triggering events
Typically events are raised by the user performing the action themselves. But there may be scenarios where you want to raise the event programatically. For example, you may want to allow a user to click on a button to refresh data, or perform the operation on your own through code. jQuery allows you to raise events through one of three methods, either the registration method, such as
click
, or one of two trigger methods: trigger
or triggerHandler
.Helper method
The easiest method to use to trigger an event is to simply call the registration function without any parameters. For example,
$('#demo').mouseenter()
will automatically perform the mouseenter
event for the element with an id of demo
.trigger and triggerHandler
Using a similar syntax to
on
, trigger
and triggerHandler
allow you to provide the name of the event as a parameter. The difference between the two is trigger
will execute for all elements in the collection, while triggerHandler
only executes the handler for the first element.<button type="button" id="first">First button</button>
<button type="button" id="Second">Second button</button>
<button type="button" id="trigger">trigger</button>
<button type="button" id="trigger-handler">triggerHandler</button>
$(function() {
$('button').click(function() {
// display the id of the button
alert(this.id);
});
$('#trigger').click(function() {
// Would alert every button's id
// including the last two
$('button').trigger('click');
});
// Would alert "first"
$('#trigger-handler').click(function() {
// Would alert "first"
$('button').triggerHandler('click');
});
});
No comments:
Post a Comment