Event binding on dynamically created elements?

Asked : Nov 17

Viewed : 91 times

I have a bit of code where I am looping through all the select boxes on a page and binding a .hover event to them to do a bit of twiddling with their width on mouse on/off.

This happens on page-ready and works just fine.

The problem I have is that any select boxes I add via Ajax or DOM after the initial loop won't have the event bound.

I have found this plugin (jQuery Live Query Plugin), but before I add another 5k to my pages with a plugin, I want to see if anyone knows a way to do this, either with jQuery directly or by another option.

javascript jquery unobtrusive-javascript events 
3 Answers

As of jQuery 1.7 you should use jQuery.fn.on with the selector parameter filled:

$(staticAncestors).on(eventName, dynamicChild, function() {});

Explanation:

This is called event delegation and works as followed. The event is attached to a static parent (staticAncestors) of the element that should be handled. This jQuery handler is triggered every time the event triggers on this element or one of the descendant elements. The handler then checks if the element that triggered the event matches your selector (dynamicChild). When there is a match then your custom handler function is executed.


Prior to this, the recommended approach was to use live():

$(selector).live( eventName, function(){} );

However, live() was deprecated in 1.7 in favour of on(), and completely removed in 1.9. The live() signature:

$(selector).live( eventName, function(){} );

... can be replaced with the following on() signature:

$(document).on( eventName, selector, function(){} );

For example, if your page was dynamically creating elements with the class name dosomething you would bind the event to a parent which already exists (this is the nub of the problem here, you need something that exists to bind to, don't bind to the dynamic content), this can be (and the easiest option) is document. Though bear in mind document may not be the most efficient option.

$(document).on('mouseover mouseout', '.dosomething', function(){
    // what you want to happen when mouseover and mouseout 
    // occurs on elements that match '.dosomething'
});

Any parent that exists at the time the event is bound is fine. For example,

$('.buttons').on('click', 'button', function(){
    // do something here
});

would apply to

<div class="buttons">
    <!-- <button>s that are generated dynamically and added here -->
</div>

answered Jan 12


In JavaScript, attaching event handlers on an element that is not yet created or does not exist on the page will throw an error. As a result, the event handler code won’t work.

For example:

//This is a div with a class of container
<div class="container"></div>
// we created a myBtn function stating that when ever we click btn, it should alert 'you clicked on the button class'
function myBtn() {
alert('you clicked on the button class')
};

// btn class does not exist  in our html page therefore this will throw an error of addEventListener of null
const btn = document.querySelector(".btn").addEventListener('click',myBtn)

In the above example, the btn class does not exist in our index.html page. Therefore, this will throw an error of addEventListener of null.

We can dynamically create an element in JavaScript and attach event handlers with these two methods:

answered Jan 12


Attaching the event dynamically, Dynamically creating elements, This is a lot simpler than you think, in our function that will create our new element, we need to attach the event handler, and function we want to assign to it, this can be done like so, When working with JavaScript, you can sometimes need to create new elements on-the-fly, and from that, you’ll need to do something with that new element. It might be a click, which more often than not will need to execute a function.

<ul id="links">
   <li class="dynamic-link">List item 1</li>
   <li class="dynamic-link">List item 2</li>
   <li class="dynamic-link">List item 3</li>
   <li class="dynamic-link">List item 4</li>
</ul>
var element = document.getElementById('id');
element.onclick = function() {
   // onclick stuff
}
var element = document.getElementById('id');

function myFunction() {
   // onclick stuff
}

element.onclick = myFunction; // Assigned
// querySelector, jQuery style
var $ = function(selector) {
   return document.querySelector(selector);
};
$('.className');

answered Jan 13


Login and Submit Your Answer
Browse other questions tagged  javascript  jquery  unobtrusive-javascript  events or ask your own question.