//

Saturday, August 17, 2019

Registering event handlers

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)
  1. events: A space separated list of the events you wish to register, such as 'click' or 'click mouseenter'
  2. selector (optional): An optional selector. We will discuss this in the next unit
  3. function: 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)
  1. $(selector): In order to use delegate, the jQuery factory must return a parent of the object you wish to wire up.
  2. selector: From the parent, provide a selector to retrieve the necessary elements.
  3. events: Same events string as before.
  4. 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 ontrigger 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

Effective Branching Strategies in Development Teams

Effective Branching Strategies in Development Teams Effective Branching Strategies in Developme...