JavaScript

What is Event Bubbling in JavaScript

What is Event Bubbling in JavaScript?

When an event happens on an element, the respective handler is run and is bubbled on to the parent element, the parent element handles the event and the event is bubbled on to its ancestors (except when bubbling is stopped).

Event Bubbling with an example

Let’s look at a sample HTML.

<table id="grid">
    <thead></thead>
    <tbody>
        <tr>
            <td>row 1 cell 1</td>
            <td>row 1 cell 2</td>
        </tr>
        <tr>
            <td>row 2 cell 1</td>
            <td>row 2 cell 2</td>
        </tr>
        <tr>
            <td>row 3 cell 1</td>
            <td>row 3 cell 2</td>
        </tr>
        <!-- some other tr rows -->
    </tbody>
</table>

When an event happens on any of the TD element in the above code, the event handler for that TD element will be fired and executed, once the TD event handler completes its operation, then its parent event listener is fired. This is called event bubbling.

So, the TR element handles the event and passes it to the tbody, the tbody handles its specific thing and passes it to the table and so on until the document object is reached.

Event Bubbling in Action

To see this in action, let’s add event listeners for every HTML tag in the above HTML. Here’s the demo in jsfiddle. Just try to click on any td cell and observe that all the listeners are fired all the way up to the document listener.

$(function(){
    $("td").on("click", function(e){
        alert($(this).text());
    });
});

Now, the above code looks pretty obvious but imagine we have 100 rows (TR) and every row is having 5 columns (TD), then the click event listener will bind to all the 500 (100 * 5) TD elements.

To solve this, we’ll just attach a listener on the grid and see if the click happened on the TD element and then take necessary action. This needs a little work, but it is just a single listener for the entire grid.

In our case, the logic should be pretty easy

$(function(){
    $("#grid").on("click", function(e){
        var cell= $(e.target); //Get the cell
        if(cell.is('TD'))
            alert('Cell data: ' + cell.text());
    });
});

Now, if we click on any of the TD element in the table we should get an alert with the cell text.

But how does it work? Because of the event bubbling.

The TD element receives a click and there is no handler attached to it so bubbled up to tr, tbody these don’t have any listeners it bubbles up to the table element which has a click event handler and is fired.

Note that once the event is handled in the table (grid) it doesn’t stop there it still bubbles up to the document object (because we didn’t stop the bubbling).

Well, this could be a problem because firing every click event until the body of the element will sometimes result in unexpected behavior in the application. We can stop this event from bubbling up the hierarchy.

To catch the bubbling we can have a listener on the parent element so that we can take appropriate action based on the target element. When this is implemented, we will call it an event delegation.

Javascript solution for event delegation

This is a javascript solution to event delegation.

var table = document.getElementById("grid");
table.onclick = function (evt) {
    var td = evt.target.closest("td"); //evt.target is the element that recieves the click
    if(!td) return; //if the click happens on any other element we can ignore the handling
    //do something with the event or take necessary action
}

If you are using plain javascript, then you should remember one thing here. The event.target is always the element that is clicked on and not the element it is bubbled up to.

jQuery event delegation

Instead of verifying if the clicked element is TD or not, jQuery has support for event delegation. So, you can specify what element to listen to when a click happens on a grid.

definition

Event delegation allows us to attach a single event listener, to a parent element, that will fire for all descendants matching a selector, whether those descendants exist now or are added in the future.- jQuery

Here’s how we can achieve event delegation in jQuery.

$(function(){
    $("#grid").on("click", "td", function(evt) {
        alert(" the td content is : " + $(this).text())
    });
});

The advantage of creating click events with event delegation is that the elements added dynamically will also receive the click events in the future. So, you don’t have to worry about dynamically adding elements.

One might think that this is the same as having the selector combined with the grid

$("#grid td").on("click", function() {});

The above event is not a delegated listener because we are attaching click event listeners for all the td elements in the #grid. Whereas the delegated listener will listen on the grid and if the click happens on the td element then the listener will be fired.

Conclusion

I’d recommend stopping the bubbling(using e.stopPropogation()) if you have handled the specific event, otherwise, it will fire the parent listeners if you have any.

With event delegation, we can have some performance improvements on the page.

jQuery event delegation is good but if you have to stop/off the event delegation, then the answer is you can’t! Yes, you cannot stop the event delegation on a specific element inside a parent container.

Disqus Comments Loading...
Share
Published by
Karthik Chintala

Recent Posts

2 Good Tools To Test gRPC Server Applications

In this post, we’ll see how to test gRPC Server applications using different clients. And… Read More

11 months ago

Exploring gRPC project in ASP.NET Core

In this post, we'll create a new gRPC project in ASP.NET Core and see what's… Read More

1 year ago

Run dotnet core projects without opening visual studio

In this blog post, we’ll see how to run dotnet core projects without opening visual… Read More

1 year ago

Programmatically evaluating policies in ASP.NET Core

Programmatically evaluating policies is useful when we want to provide access or hide some data… Read More

1 year ago

Multiple authorization handlers for the same requirement in ASP.NET Core

We saw how we could set up policy-based authorization in our previous article. In this… Read More

1 year ago

Policy-Based Authorization in ASP.NET Core

What is policy-based authorization and how to set up policy-based authorization with handlers and policies… Read More

1 year ago

This website uses cookies.