Event Delegation in JavaScript

Anyone who has spent a long time building JavaScript applications knows how important event handlers can be for processing certain common user actions, such as mouse clicks, windows and keyboard events, and so forth. However, while event handlers are a powerful feature for creating highly responsive JavaScript programs with relative ease, they have been overused way too frequently. This has implications for how quickly certain kinds of JavaScript programs run. Fortunately, JavaScript event delegation can help solve many of these problems. This four-part series explains how.

Many web designers now implement event handlers more carefully, and resist the temptation to fire up functions and classes each time users click on different elements across a web page. 

Regardless of this promising scenario, it’s common to see JavaScript programs that use event handlers in a poor and inefficient way. Let me explain this concept a bit further with an example: suppose for a moment that there’s a server-side application that pulls a product catalog from a database table and displays its contents via a typical HTML table.  

So far, so good, right? Now, it’s possible to extend the behavior of this application with some unobtrusive JavaScript and assign a click event handler to each cell of the table, so every time a user clicks on a product item, a tooltip will be displayed showing some additional information about that product. Simple and effective, right? 

Well, unfortunately, that’s really not so effective. Considering that this HTML table might be populated with tens of products items, in theory the same number of click handlers should be assigned to each table cell. This could consume a lot of RAM. Naturally, for small machines this heavy load might cause system hang-ups or, in the best case, browsers running very slowly.  

So, how do we solve this issue efficiently and elegantly? The answer is simply with JavaScript event delegation. As you know, events have two different phases, called “capture” and “bubble” respectively. Thus, returning to the previous example, it’d be feasible to assign only one click handler to the whole HTML table, and then by using the bubbling phase, to determine what cell was clicked by the user.  

This process is known popularly as event handling delegation, and in this group of articles, I’ll be coding some concrete examples that will help you grasp how it works, so you can implement it within your own JavaScript programs.  

Now that you’ve digested the theory behind using event delegation in JavaScript, it’s time to learn how to take advantage of it with functional code samples. Ready? Then let’s get started! 

{mospagebreak title=What you shouldn’t do with JavaScript event handlers}

A good place to start demonstrating the real benefits to using JavaScript event delegation is with recreating the hypothetical situation discussed in the introduction, where one click handler is inefficiently assigned to each cell of an HTML table.  

In this particular case, the purpose of doing this is to create a simple highlighting effect on all of the table cells. This example could be implemented with the following code:  

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<title>Classic event handling with JavaScript</title>

<script language="javascript">

// highlight table cells when web page has been loaded

window.onload=function(){

if(document.getElementsByTagName&&document.getElementById&&document.createElement){

// get target table

var mytable=document.getElementById(‘mytable’);

if(!mytable){return};

// get cells in target table

var cells=mytable.getElementsByTagName(‘td’);

if(!cells){return};

// assign ‘onclick’ event handler to each table cell

for(var i=0;i<=cells.length;i++){

cells[i].onclick=function(){

this.className=’highlighted';

}

}

}

}

</script>

<style type="text/css">

table{

width: 500px;

border: 1px solid #000;

}

td{

font: normal 10pt Arial, Helvetica, sans-serif;

color: #000;

background: #9fc;

border: 1px solid #000;

}

.highlighted{

background: #0c9;

}

</style>

</head>

<body>

<h1>Classic event handling with JavaScript</h1>

<table id="mytable">

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

</table>

</body>

</html> 

Despite its simplicity, the above example shows how to build a JavaScript-based highlighting effect by assigning a click handler to each cell of an HTML table. As you can see, every time a user clicks on an individual cell, a “highlight” CSS class will be tied to it, thus achieving the effect. 

Logically, the down side to using this approach is that if the HTML table contains a large number of cells, then the browser will be obligated to process the same number of click handlers, which may seriously slow the performance of computers with a limited amount of RAM. 

Okay, now that you’ve learned the “bad” way to work with JavaScript event handlers, it’s time to see how the previous example can be partially rebuilt by taking advantage of the functionality provided by event delegation.  

To see how this brand new example will be developed, please click on the link that appears below and keep reading.  

{mospagebreak title=Taking advantage of JavaScript event delegation} 

As you hopefully learned at the beginning of this article, event delegation rests its functionality on the “bubbling” phase of a particular JavaScript event. In a case like the example created in the previous section, it’s perfectly possible (and desirable, actually) to utilize it to attach only one click handler to the whole HTML table, and later on, determine what cell triggered that specific event. 

To accomplish that task in a simple fashion, I’m going to define a couple of JavaScript functions. The first one will be tasked with determining which element of the web page is the source of a specific event, and the second one will be charged with checking to see if this element is a table cell. If it is, then the highlight effect will be applied to it. That’s it.  

The signature of these JavaScript functions are as following: 

// get target element

function getEventTarget(e){

var e=e || window.event;

return e.target || e.srcElement;

}

// check if target is a table cell

function highlightCell(e){

var target=getEventTarget(e);

if(target.tagName.toLowerCase()==’td’) {

target.className=’highlighted';

}

}

As I explained before, all that the first “getEventTarget()” function does is return the source of the web page element that fires a specific event, while the second function, called “highlightCell(),” not surprisingly checks to see if the returned element is a cell table. If this is true, then the “highlighted” CSS class is tied up to it. 

So what have we achieved in using this approach? Quite a bit, actually. Obviously, the major advantage is that with these handy functions at our disposal, it’s possible to assign one click handler to the HTML table shown in the previous segment, and then implement the highlighting effect only in the cell that was originally clicked. See how useful it is to use event delegation to avoid coding redundant, memory-consuming handlers? I guess you do.  

However, the best way to grasp the actual functionality of event delegation is by looking over the complete source code that corresponds to the example developed earlier.  

Thus, in the following section I’m going to list for you all of the parts that comprise the example, so click on the link below and read the next few lines.  

{mospagebreak title=The event delegation approach in action} 

In the segment that you just read, I defined a pair of JavaScript functions to implement the event delegation approach on a sample HTML table. However, it’s necessary to gather this JavaScript snippet, along with the CSS code and structural markup of this sample application, in one single (X)HTML file. 

Therefore, here’s the signature of this sample file:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<title>Example on JavaScript event delegation (with click event)</title>

<script language="javascript">

// get target element

function getEventTarget(e){

var e=e || window.event;

return e.target || e.srcElement;

}

// check if target is a table cell

function highlightCell(e){

var target=getEventTarget(e);

if(target.tagName.toLowerCase()===’td’) {

target.className=’highlighted';

}

}

// run functions when web page has been loaded

window.onload=function(){

if(document.getElementsByTagName&&document.getElementById&&document.createElement){

var mytable=document.getElementById(‘mytable’);

if(!mytable){return};

// assign ‘onclick’ event handler to table (not cells)

mytable.onclick=function(e){

// determine target element and highlight table cell

highlightCell(e);

}

}

}

</script>

<style type="text/css">

table{

width: 500px;

border: 1px solid #000;

}

td{

font: normal 10pt Arial, Helvetica, sans-serif;

color: #000;

background: #9fc;

border: 1px solid #000;

}

.highlighted{

background: #0c9;

}

</style>

</head>

<body>

<h1>Event delegation in JavaScript (with click event)</h1>

<table id="mytable">

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

<tr>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

<td>This is the content of the cell</td>

</tr>

</table>

</body>

</html>

Definitely, the above (X)HTML file now looks much better. By means of event delegation, only one click handler is required to apply the highlighting effect on each cell of the HTML table, which makes the whole application work much more efficiently. In addition, here’s a screen shot that shows how this effect is rendered by the browser: 

Hopefully, this initial example gives you a clear idea of how to successfully implement event delegation in JavaScript. As always, feel free to play with all the code samples developed in this article to give you a better grounding in using this clever approach. 

Final thoughts 

In this first installment of the series, I introduced you to implementing event delegation in JavaScript by reducing the number of click handlers attached to an HTML table. It’s fair to say here that event delegation isn’t always so well-supported by all JavaScript events; you should be aware of this when using this technique with “mousemove” and keyboard-related events. 

It can be implemented neatly with “mouseovers,” however. Thus, in the next part of this series I’ll be explaining how to use event delegation with this kind of event. Don’t miss the upcoming article!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan