By Eli

2008-10-14 23:25:19 8 Comments

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.


@Mustkeem K 2018-06-14 11:15:18

This is done by event delegation. Event will get bind on wrapper-class element but will be delegated to selector-class element. This is how it works.

$('.wrapper-class').on("click", '.selector-class', function() {
    // Your code here

#Note: wrapper-class element can be anything ex. document, body or your wrapper. Wrapper should already exist. However, selector doesn't necessarily needs to be presented at page loading time. It may come later and the event will bind on selector without fail.

@Asad Ali 2020-08-05 16:36:18

Yes, but it'll create event propagation for elements. you need to add target the specific dynamic element and stop event propagation.

@Mustkeem K 2020-08-06 07:18:13

In case you bind same event on parent and descendent element than you can stop it using event.stopPropagation()

@dev.e.loper 2009-07-30 15:34:49

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

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


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 -->

@Sam Dutton 2011-02-17 11:47:22

Note that the live method only works for certain events, and not others such as loadedmetadata. (See the caveats section in the documentation.)

@Felix Kling 2013-06-07 11:21:43

Learn more about event delegation here:

@Ram Patra 2014-11-12 12:33:18

Any way to accomplish this with pure javascript/vanilla js?

@Dave 2014-12-08 17:46:59

@Ramswaroop anything you can do in jQuery can be accomplished without jQuery. Here's a good example of event delegation without jQuery

@Ram Patra 2014-12-09 07:14:53

@dave I wonder why the answer you pointed out isn't listed here. Eli has clearly asked for a solution without any plugin if possible.

@A. Wolff 2015-02-04 14:29:32

Prior to jq1.7 and for jq1.4.2>, the recommended method was to use delegate(): (which btw isn't removed from jq) As of jQuery 1.7, .delegate() has been superseded by the .on() method. For earlier versions, however, it remains the most effective means to use event delegation

@Tech Savant 2015-05-16 23:23:09

How do you get a value from dynamic element without binding a click event.

@madzohan 2015-07-03 12:48:20

and what if dynamicChild structure is complicated and maybe change in future? I want bind all objects with someClass to handler (there are in different DOM positions, static only modal div) and declare this binding only one time for all future objects in different positions in DOM ... now I am using workaround by attaching onclick="..."

@Ben Dol 2015-12-10 21:12:21

how do you off events registered this way? simply calling each again and calling off() doesn't work.

@minhajul 2016-06-13 17:50:18

what happens when you cant get the selector(id/class) you just have the element at hand?

@pilat 2016-11-11 20:18:19

struggling to have something done on when the element has just been ready for manipulations. like `$(document).on('load', '.dyn-el', function() { /* ... */});'

@SaidbakR 2018-05-09 18:10:35

Some other answers regarded staticAncestors to be the document as all. I think this may cost more performance when there is already parent container is already found. i.e make the search more narrow as possible is better.

@ryes31 2020-06-24 01:27:36

This just saved me a lot of wasted time. Thank you for this answer!

@Vatsal 2015-11-21 12:01:48

I prefer using the selector and I apply it on the document.

This binds itself on the document and will be applicable to the elements that will be rendered after page load.

For example:

$(document).on("click", 'selector', function() {
    // Your code here

@autopilot 2018-04-09 04:21:54

the selector shouldn't be enclosed by $, thus the correct format will be $(document).on( "click" , "selector" , function() { // Your code here });

@Rory McCrossan 2018-06-20 14:57:31

It's also pointless to wrap a jQuery object around the selector variable, when it must either contain a string or Element object which you can just pass directly to that argument of on()

@Rohit Suthar 2016-06-30 06:25:30

Try like this way -

$(document).on( 'click', '.click-activity', function () { ... });

@Prasad De Silva 2017-04-18 19:47:07

Another flexible solution to create elements and bind events (source)

// creating a dynamic element (container div)
var $div = $("<div>", {id: 'myid1', class: 'myclass'});

//creating a dynamic button
 var $btn = $("<button>", { type: 'button', text: 'Click me', class: 'btn' });

// binding the event
 $ () { //for mouseover--> $btn.on('mouseover', function () {

// append dynamic button to the dynamic container

// add the dynamically created element(s) to a static element

Note: This will create an event handler instance for each element (may affect performance when used in loops)

@Ronnie Royston 2018-06-08 02:53:27

I prefer to have event listeners deployed in a modular function fashion rather than scripting a document level event listener. So, I do like below. Note, you can't oversubscribe an element with the same event listener so don't worry about attaching a listener more than once - only one sticks.

var iterations = 4;
var button;
var body = document.querySelector("body");

for (var i = 0; i < iterations; i++) {
    button = document.createElement("button");
    button.addEventListener("click", myButtonWasClicked);

function myButtonWasClicked(e) {
    console.log(; //access to this specific button

@William 2018-10-22 10:18:43

I prefer this implementation; I just have to set up a call back

@truongnm 2018-06-08 02:29:14

Bind the event to a parent which already exists:

$(document).on("click", "selector", function() {
    // Your code here

@Evhz 2018-05-18 00:13:34

I was looking a solution to get $.bind and $.unbind working without problems in dynamically added elements.

As on() makes the trick to attach events, in order to create a fake unbind on those I came to:

const sendAction = function(e){ ... }
// bind the click
$('body').on('click', 'button.send', sendAction );

// unbind the click
$('body').on('click', 'button.send', function(){} );

@Fabian Bigler 2018-11-09 11:28:06

The unbinding does not work, this simply adds another event which points to an empty function...

@Ram Patra 2014-12-09 07:59:49

This is a pure JavaScript solution without any libraries or plugins:

document.addEventListener('click', function (e) {
    if (hasClass(, 'bu')) {
        // .bu clicked
        // Do your thing
    } else if (hasClass(, 'test')) {
        // .test clicked
        // Do your other thing
}, false);

where hasClass is

function hasClass(elem, className) {
    return elem.className.split(' ').indexOf(className) > -1;

Live demo

Credit goes to Dave and Sime Vidas

Using more modern JS, hasClass can be implemented as:

function hasClass(elem, className) {
    return elem.classList.contains(className);

@zloctb 2016-01-06 14:57:48

@Eugen Konkov 2016-08-09 10:07:47

You may use Element.classList instead of splitting

@Ram Patra 2016-08-09 10:59:44

@EugenKonkov Element.classList is not supported supported on older browsers. For example, IE < 9.

@Ram Patra 2017-06-29 09:25:24

A nice article on how to get things done using vanilla script instead of jQuery -…

@Andreas Trantidis 2017-07-06 13:06:53

how about bubbling? What if the click event happened on a child of the element you are interested in?

@Ram Patra 2017-07-06 13:19:56

@AndreasTrantidis you have to check for the class of the child element:

@leaf 2017-09-16 07:01:23

Here is why dynamically created elements do not respond to clicks :

var body = $("body");
var btns = $("button");
var btnB = $("<button>B</button>");
// `<button>B</button>` is not yet in the document.
// Thus, `$("button")` gives `[<button>A</button>]`.
// Only `<button>A</button>` gets a click listener.
btns.on("click", function () {
// Too late for `<button>B</button>`...
<script src=""></script>

As a workaround, you have to listen to all clicks and check the source element :

var body = $("body");
var btnB = $("<button>B</button>");
var btnC = $("<button>C</button>");
// Listen to all clicks and
// check if the source element
// is a `<button></button>`.
body.on("click", function (ev) {
  if ($("button")) {
// Now you can add any number
// of `<button></button>`.
<script src=""></script>

This is called "Event Delegation". Good news, it's a builtin feature in jQuery :-)

var i = 11;
var body = $("body");
body.on("click", "button", function () {
  var letter = (i++).toString(36).toUpperCase();
  body.append($("<button>" + letter + "</button>"));
<script src=""></script>

@user4642212 2020-07-26 00:18:03

It’s also possible to assign var body = $("body").on(); directly.

@Fakhrul Hasan 2017-09-27 15:42:58

        <title>HTML Document</title>
        <script src=""></script>

        <div id="hover-id">
            Hello World

                $(document).on('mouseover', '#hover-id', function(){

                $(document).on('mouseout', '#hover-id', function(){

@Palec 2017-09-30 11:07:42

While this code snippet may solve the problem, it doesn't explain why or how it answers the question. Please include an explanation for your code, as that really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.

@guest271314 2017-04-05 07:11:21

You can attach event to element when dynamically created using jQuery(html, attributes).

As of jQuery 1.8, any jQuery instance method (a method of jQuery.fn) can be used as a property of the object passed to the second parameter:

function handleDynamicElementEvent(event) {
  console.log(event.type, this.value)
// create and attach event to dynamic element
jQuery("<select>", {
    html: $.map(Array(3), function(_, index) {
      return new Option(index, index)
    on: {
      change: handleDynamicElementEvent
<script src="">

@Ronen Rabinovici 2013-08-09 09:51:28

There is a good explanation in the documentation of jQuery.fn.on.

In short:

Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on().

Thus in the following example #dataTable tbody tr must exist before the code is generated.

$("#dataTable tbody tr").on("click", function(event){

If new HTML is being injected into the page, it is preferable to use delegated events to attach an event handler, as described next.

Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. For example, if the table exists, but the rows are added dynamically using code, the following will handle it:

$("#dataTable tbody").on("click", "tr", function(event){

In addition to their ability to handle events on descendant elements which are not yet created, another advantage of delegated events is their potential for much lower overhead when many elements must be monitored. On a data table with 1,000 rows in its tbody, the first code example attaches a handler to 1,000 elements.

A delegated-events approach (the second code example) attaches an event handler to only one element, the tbody, and the event only needs to bubble up one level (from the clicked tr to tbody).

Note: Delegated events do not work for SVG.

@msanjay 2014-05-09 18:14:30

this'd be a better accepted answer because it'd be faster to delegate from the specific table rather than all the way from the document (the search area would be much smaller)

@Gone Coding 2014-11-12 12:06:54

@msanjay: Although targetting the search closer to the elements is preferred, the search/speed difference is very minor in practice. You would have to click 50,000 times a second to notice anything :)

@JoeBrockhaus 2014-11-25 17:26:50

Can this approach be applied to handling checkbox clicks in a row by changing tr to an appropriate selector, like 'input[type=checkbox]', and this would be automatically handled for newly inserted rows?

@Dennis Fazekas 2019-10-03 21:31:50

Thank you! This solve my problem. This simple statement was my issue, "Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to..."

@Kalpesh Patel 2016-11-30 09:07:46

Use the .on() method of jQuery to attach event handlers to live element.

Also as of version 1.9 .live() method is removed.

@Mensur Grišević 2016-08-11 16:16:58

you could use

$('.buttons').on('click', 'button', function(){
    // your magic goes here


$('.buttons').delegate('button', 'click', function() {
    // your magic goes here

these two methods are equivalent but have a different order of parameters.

see: jQuery Delegate Event

@Rory McCrossan 2018-06-20 14:58:29

delegate() is now deprecated. Do not use it.

@Aslan Kaya 2016-03-26 02:15:42

Take note of "MAIN" class the element is placed, for example,

<div class="container">
     <ul class="select">
         <li> First</li>

In the above scenario, the MAIN object the jQuery will watch is "container".

Then you will basically have elements names under container such as ul, li, and select:

$(document).ready(function(e) {
    $('.container').on( 'click',".select", function(e) {

@MadeInDreams 2016-01-22 01:06:59

Event binding on dynamically created elements

Single element:

$(document.body).on('click','.element', function(e) {  });

Child Element:

 $(document.body).on('click','.element *', function(e) {  });

Notice the added *. An event will be triggered for all children of that element.

I have noticed that:

$(document.body).on('click','.#element_id > element', function(e) {  });

It is not working any more, but it was working before. I have been using jQuery from Google CDN, but I don't know if they changed it.

@MadeInDreams 2016-01-23 16:29:43

Yeap and they are not saying (document.body) its says ancestor wich could be pretty much anything

@Martin Da Rosa 2015-10-07 17:43:38

Another solution is to add the listener when creating the element. Instead of put the listener in the body, you put the listener in the element in the moment that you create it:

var myElement = $('<button/>', {
    text: 'Go to Google!'

myElement.bind( 'click', goToGoogle);

function goToGoogle(event){

@ddlab 2017-05-11 19:58:34

Your code contains 1 mistake: myElement.append('body'); must be myElement.appendTo('body');. On the other hand, if there is no need for the further use of variable myElement it's easier and shorter this way: $('body').append($('<button/>', { text: 'Go to Google!' }).bind( 'click', goToGoogle));

@Fazi 2011-12-21 07:26:56

You can use the live() method to bind elements (even newly created ones) to events and handlers, like the onclick event.

Here is a sample code I have written, where you can see how the live() method binds chosen elements, even newly created ones, to events:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Untitled Document</title>

        <script src=""></script>
        <script src=""></script>

        <input type="button" id="theButton" value="Click" />
        <script type="text/javascript">
                    $('.FOO').live("click", function (){alert("It Works!")});
                    var $dialog = $('<div></div>').html('<div id="container"><input type ="button" id="CUSTOM" value="click"/>This dialog will show every time!</div>').dialog({
                                                                                                         autoOpen: false,
                                                                                                         tite: 'Basic Dialog'
                        //$('#container').append('<input type="button" value="clickmee" class="FOO" /></br>');
                        var button = document.createElement("input");
                    /* $('#FOO').click(function(){
                                                     alert("It Works!");
                                                 }); */

@Greg Borenstein 2008-10-14 23:35:39

You could simply wrap your event binding call up into a function and then invoke it twice: once on document ready and once after your event that adds the new DOM elements. If you do that you'll want to avoid binding the same event twice on the existing elements so you'll need either unbind the existing events or (better) only bind to the DOM elements that are newly created. The code would look something like this:

function addCallbacks(eles){


// ... add elements ...

@theflowersoftime 2011-08-24 09:24:11

This post really helped me get a grasp on a problem I was having loading the same form and getting 1,2,4,8,16... submissions. Instead of using .live() I just used .bind() in my .load() callback. Problem solved. Thanks!

@nickf 2008-10-14 23:31:40

You can add events to objects when you create them. If you are adding the same events to multiple objects at different times, creating a named function might be the way to go.

var mouseOverHandler = function() {
    // Do stuff
var mouseOutHandler = function () {
    // Do stuff

$(function() {
    // On the document load, apply to existing elements
    $('select').hover(mouseOverHandler, mouseOutHandler);

// This next part would be in the callback from your Ajax call
    .append( /* Your <option>s */ )
    .hover(mouseOverHandler, mouseOutHandler)
    .appendTo( /* Wherever you need the select box */ )

@Ankit Kathiriya 2015-12-18 08:48:51

Any parent that exists at the time the event is bound and if your page was dynamically creating elements with the class name button you would bind the event to a parent which already exists

  //Particular Parent chield click
  //Dynamic event bind on button class  
    alert("Dymamic Clicked");
<script src=""></script>
<div class="buttons">
  <input type="button" value="1">
  <input type="text">
  <input type="button" value="5">  

@user670265 2011-03-21 22:35:24

Try to use .live() instead of .bind(); the .live() will bind .hover to your checkbox after the Ajax request executes.

@chridam 2014-06-17 12:30:04

The method live() was deprecated in version 1.7 in favor of on and deleted in version 1.9.

Related Questions

Sponsored Content

54 Answered Questions

[SOLVED] How to create GUID / UUID?

  • 2008-09-19 20:01:00
  • Jason Cohen
  • 1889758 View
  • 4260 Score
  • 54 Answer
  • Tags:   javascript guid uuid

30 Answered Questions

[SOLVED] jQuery scroll to element

57 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

39 Answered Questions

[SOLVED] Creating multiline strings in JavaScript

63 Answered Questions

[SOLVED] How can I merge properties of two JavaScript objects dynamically?

80 Answered Questions

[SOLVED] How do I detect a click outside an element?

15 Answered Questions

[SOLVED] How to move an element into another element?

  • 2009-08-14 20:14:45
  • Mark Richman
  • 1133947 View
  • 1709 Score
  • 15 Answer
  • Tags:   javascript jquery html

14 Answered Questions

[SOLVED] How does data binding work in AngularJS?

7 Answered Questions

[SOLVED] How do I bind Twitter Bootstrap tooltips to dynamically created elements?

Sponsored Content