JQuery 3 - Reinventing Events
Written by Ian Elliot   
Monday, 03 April 2017
Article Index
JQuery 3 - Reinventing Events
Bubbling & Capture
Event Data
Bubbling & Delegation

Bubbling & Capture

We also have to consider the way events work in the DOM. In particular the way events "bubble".

In an HTML page different UI elements are nested inside one another. For example,

<div id="div1">
   Some Text
  <button id="button1">
    Click me
  </button>
</div>

defines a button contained inside a div. If we now define an event handler for each:

div1.addEventListener("click",myEventHandler1);
button1.addEventListener("click",myEventHandler2);
function myEventHandler1(e){
 alert("div");
}
function myEventHandler2(e){
 alert("button");
}

you can discover what happens when an event occurs on the inner UI element, i.e. the button. 

With event bubbling the innermost item handles the event first and then passes it up in turn to the outer items. So if you click on the button you will see the button alert and then the div alert. 

Why do we want events to bubble?

The reason is that there might be an action which has to be performed by the containing UI element when a child element is used. For example, the div event handler might reset all of the child buttons it contains. It might also be the case that you don't want to implement event handlers for all of the inner elements. In this case you could allow the event to bubble up to the outermost UI element and handle it there. Notice that the event object passed to the handler can be used to find out what UI element the event actually occurred on. 

For example, if  you define three buttons within a div you can handle a click on any button with an event handler registered to the div simply because the button click events bubble up:

<div id="div1">
<button id="button1">Click me</button>
<button id="button2">Click me</button>
<button id="button3">Click me</button>
</div>
<script>
 div1.addEventListener("click",myEventHandler1);
 function myEventHandler1(e){
  alert(e.target.id);
 }
</script>

When you click on any button the alert box correctly shows the id of the button. 

By default all events bubble up the UI hierarchy. 

The other way to allow events to propagate is called capture and this can be thought of as bubbling down - sometimes called trickling down.

In this case when an event occurs on an inner UI element it is the topmost enclosing UI element that gets to handle the event first. 

To select capture you have to specify a third parameter - useCapture - when registering the event handler. So let's change the previous example of a button inside a div to use capture:

<div id="div1">
   Some Text
 <button id="button1">
  Click me
 </button>
</div>
<script>
div1.addEventListener("click",myEventHandler1,true);
button1.addEventListener("click",myEventHandler2); 
   function myEventHandler1(e){
           alert("div");  
    }
function myEventHandler2(e){
    alert("button"); }
</script>

Notice that the div event handler is now registered with useCapture set to true. This means that all click events that occur on UI elements that are contained by it are handled by it and then passed down through  child elements back to the element that the event occurred on. Now if you click on the button you will see the div message first and the button message second. 

In most cases it is much simpler to use bubbling because older browsers don't support capture. 

Basic jQuery Events - on, off, one

Event handling in older browsers is a mess. You can spend a lot of time trying to write event handling code that works as widely as possible but it is better to simply give in and use jQuery which smooths out the differences. jQuery also more or less re-implements the event handling system to make is more logical and more powerful. 

It is important to realize the jQuery really is reimplementing the event handling system, and this means that it works in ways that are different from the browser's native event handling and even from the W3C events specification.

In jQuery you register an event handler using on and remove an event handler using off. These are the only two functions you need but there are others that add some versatility. Versions of jQuery before 3 made use of a set of now deprecated functions - you can ignore these.

The on function has the basic form:

.on(events,selector,data,handler)

where selector and data are optional and both are described in detail later in the chapter.

The simplest use of the on function is to attach a handler to an element:

$("#button1").on("click",myEventHandler);

This attaches myEventHandler to the element with id button1. Of course, if you select multiple elements the same event handler is attached to them all. 

If you want to set multiple events in one operation you can use an alternative version of on:

.on(eventsList,selector,data)

In this case the first parameter is an object of key/value pairs. The keys are events and the values are event handlers. 

For example:

$("#button1").one({click:myEventHandler,
                      dbclick:myEventHandler2});

sets two event handlers one for a click and one for a double-click. 

Notice that if you set multiple event handlers on an element then they will be called in the order in which they were added. This is, of course, different to raw JavaScript events where the order is undefined. 

jQuery also allows you to add the same function as an event handler on the same element more than once. This too is different to raw JavaScript events where multiple copies of the same event handler are simply discarded. Having multiple copies of the same function means you can trigger the action more than once for each event and you can also pass different parameters if you want to - see later. 

Another jQuery extension to event handling is the one function. This works like on, but any event handler you add using it will only be triggered once on each element it has been added to. 

For example if you use:

$("#button1").one("click",myEventHandler);

then the event handler is added as before, but now it will only be called once. That is, the user can only click the button and trigger the event handler once. 

You can remove an event handler using the off function. 

If you want to remove a specific event handler use:

.off(events,selector,handler);

which will remove the handler that was added using the same event, selector and handler.

If you want to remove a set of event handlers you can pass an object of key/value pairs with the key being the event name and the value being the event handler to remove. 

.off(events,selector);

Finally if you want to remove all event handlers for a specific event use:

.off("event");

and to remove all events from an element use:

.off();

For example, to remove the click event handler given earlier, use

$("#button1").off("click",myEventHandler);

To remove all click event handlers, use

$("#button1").off("click");

and to remove all event handlers of any type, use

$("#button1").off();

This is all you need to know about adding and removing events at the basic level but we need to fill out details of how the selector is used to specify delegated events and how to implement custom events - see later. 

The Event Handler

When an event handler is called in response to an event it is passed some parameters that help it work with the event. Standard JavaScript event handlers are passed an Event object which has properties determined by the type of event. jQuery provides its own Event object which is a "normalized" version of the raw JavaScript event object.

That is the jQuery event object provides the same information independent of the browser in use. You can access the native event object via the originalEvent property and this is sometimes necessary for events that provide additional information. 

In addition to the Event parameter the event handler is also provided with the element that the event occurred on as this. Notice that this is a raw DOM Element and if you want to use it as a jQuery object you will need to wrap it in $(this).

There are a lot of possible event properties that you could work with depending on the type of event but there are a few that are common to all events. These are briefly described below, although a full explanation is postponed until a later section.

  • There is a set of properties that tell you about the type of event and the element it occurred on:

event.type

gives the name of the event for example "click". 

event.namespace

give the namespace that was specified when the event was triggered. This is covered in the section on custom events.

event.timeStamp

The time that the event occurred measured in milliseconds from January 1,1970.

event.data

An object of custom data passed to the event handler. This is another jQuery extension of the basic event handling mechanism. 

  • There are a set of properties concerned with the way the event bubbles:

event.target

This is the element that the event occurred on e.g. the element that the user actually clicked on. This is always the deepest or innermost element of a nested set of elements. Notice that because of event bubbling this isn't always the same as the element the event was added to.   

event.currentTarget

The element that the bubbling phase has reached. 

event.delegateTarget

The element that the event handler was attached to.

event.relatedTarget

Any element that is also involved in the event. This is only supplied for events where there is another element involved. For example, when a mouseout event occurs the relatedTarget is the element the mouse pointer entering. 

event.result

The last value returned by an event handler.

<ASIN:1871962501>



Last Updated ( Thursday, 05 May 2022 )