Binding DOM Element question ?

Alex Lord
Alex Lord used Ask the Experts™
on
Is it possible to destory a bind on the DOM and recreate it ? let say i add data to a table from a Ajax request i would need to rebind that to the dom for the new inserted data ?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Analyst Developer
Distinguished Expert 2018
Commented:
The best way is to use the event delegation .on() when you want to bind the event to the future inserted elements to the DOM dynamically like :

$('table').on('click', 'button', function(){
    //Do something
})

Open in new window


That will attach the click event to all the buttons inside the table even those who are added dynamically by the ajax request.

Whatever you could always use the jQuery methods .unbind() and .off() to detach the events.
Most Valuable Expert 2017
Distinguished Expert 2018

Commented:
Don't bind / unbind to do what you are doing - it is not necessary. There is a way to do a single bind that will cater for your dynamically allocated elements.

Let's take a more detailed look at what happens when you bind an event handler to an element with jQuery - we will use the click() event for this example but this applies to any event that can be triggered on a DOM element.

$('.myTable td:first-child a').click(function() {
  console.log('Clicked');
});

Open in new window


The equivalent of doing this in JavaScript would be
var els = document.querySelectorAll('.myTable td:first-child a');
els.forEach(item => {
   item.addEventListener('click', function() {
     console.log('Clicked');
   });
});

Open in new window


It is useful to go back to the original JavaScript because we can see that there is no magic function in the DOM that adds an event handler to all target elements (the way jQuery does). You have to add an event listener to each of the matched nodes.

What this is showing us is that when the above code runs it will only bind to elements that are actually in the DOM at the time it runs. If we add more elements after document load they will not be bound to the handler. Likewise if we remove elements they will destroy the binding when deleted.

So, how do we cater for dynamically added items.

As described in the above post we use .on(). What the on() function allows us to do, is bind an event handler to a parent of the elements we are interested in and then specify a class / node of the target elements we are interested in targeting.
As long as the parent is static i.e. is there when the on() function runs AND remains in the document then our code will work.

So how do we do this?

Let's take the following example
<table class="myTable table">
  <tr>
    <td><a>Click me</a></td>
    <td>Cell 2</td>
  </tr>
  <tr>
    <td><a>Click me</a></td>
    <td>Cell 2</td>
  </tr>
</table>

Open in new window

Assume that the <table> parent is static - it does not get replaced (if this is not the case then simply choose / create a parent of the table that is static)

We can now bind our event handler like this
$('.myTable').on('click', 'td:first-child a', function() {
});

Open in new window


When an <a> element in the first cell of myTable is clicked, because there is no event handler expressly bound to that element, the event bubbles up until it gets to the .myTable node where there is an event handler. This handler, because it was created with the .on() function, checks the event target to see where the click originated from - if that event target matches the selector passed to the .on() function then the callback code will fire.

This way you can bind a handler to elements that don't yet exist - without having to bind / unbind / rebind events when dynamic content is added.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial