Explain Codes LogoExplain Codes Logo

Jquery click not working for dynamically created items

javascript
event-handling
jquery
backbone-js
Anton ShumikhinbyAnton Shumikhin·Nov 30, 2024
TLDR

Utilize jQuery's event delegation with .on() to assign click handlers to elements added dynamically. Attach the event to a parent that already exists in DOM, specifying the dynamic elements' selector:

$('#parent').on('click', '.dynamic-child', function() { // It's peanut butter jelly time! Do something when a dynamic child is clicked! });

#parent should be a parent container that already exists in the DOM, while .dynamic-child corresponds to the elements added dynamically. This ensures that click events are triggered even for elements that appear on the fly.

Delegation vs Direct Binding: Understanding the Underlyings

The problem with direct event methods like .click() is that they only attach to elements present at the initial page load. So, if we add elements dynamically, our registered events won't recognize these latecomers. This is where .on() trips in with its fancy suit to save the day—it attaches the event to a parent that exists from the start, delegating the event down to dynamic elements, no matter when they decide to show up.

Scoped Delegation: More Precise Event Handling

Although using $(document) as the event delegate is a surefire way to catch events for dynamically created elements, it also means every click goes to the document level. It's not unlike chasing all the city flies with an enormous SWAT van... Imagine the traffic! For this reason, a more recommended approach is to use a closer parent—a traffic cop at the neighborhood level rather than city level.

This example illustrates how a closer parent works:

$('#table-container').on('click', 'tr.row-clickable', function() { // You clicked me! Now, shall we dance? });

Harnessing the Power of Backbone.js in Event Handling

For larger applications, or when having more complex interactions, Backbone.js surfaces as a powerful tool for event handling. Offering a structured way to attach and to react to events, it utilizes the events object within the View component.

Let's see a Backbone.js approach in action:

let TableView = Backbone.View.extend({ el: '#table-container', events: { 'click tr.row-clickable': 'handleRowClick' }, handleRowClick: function(event) { // Time to play "catch the click"! Your logic goes here. } });

tip: In this Backbone.js version, el serves as the parent for our event delegation, while events bind our events to our elements. This structure provides a convenient array of controls over our event bindings.

Beyond Common Practice: Strategic Event Handling Tactics

In the Absence of .on()

Sometimes, you might be dealing with jQuery before it pulled .on() out of its magic hat (versions before 1.7). In such cases, .delegate() is your new best friend.

$('#parent').delegate('.dynamic-child', 'click', function() { // Hello from the past! Your event actions go here. });

Keeping up with AJAX

There will be times when you need to add dynamic elements through AJAX calls. When this is the case, set up event delegation before making the AJAX call or within its successful return to ensure event handlers bind properly:

$.ajax({ // Your AJAX call settings go here. }).done(function() { // Now, this is the AJAX-party! Register your events here after AJAX success. });

Preparing Your Dynamic HTML for Event Handling

Inserting raw HTML into the DOM without proper wrapping is like sending a delicate package without bubble wrap—the ride could get rough, causing events not to bubble properly. To avoid this, wrap your new HTML elements inside a parent element:

$('#parent').html('<div class="dynamic-child">Click me! We will make history together!</div>');