[javascript] Event binding on dynamically created elements?

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.

This question is related to javascript jquery events unobtrusive-javascript

The answer is


Try like this way -

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

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


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.

_x000D_
_x000D_
var iterations = 4;_x000D_
var button;_x000D_
var body = document.querySelector("body");_x000D_
_x000D_
for (var i = 0; i < iterations; i++) {_x000D_
    button = document.createElement("button");_x000D_
    button.classList.add("my-button");_x000D_
    button.appendChild(document.createTextNode(i));_x000D_
    button.addEventListener("click", myButtonWasClicked);_x000D_
    body.appendChild(button);_x000D_
}_x000D_
_x000D_
function myButtonWasClicked(e) {_x000D_
    console.log(e.target); //access to this specific button_x000D_
}
_x000D_
_x000D_
_x000D_


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.


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
$("<select></select>")
    .append( /* Your <option>s */ )
    .hover(mouseOverHandler, mouseOutHandler)
    .appendTo( /* Wherever you need the select box */ )
;

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

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

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) {
        alert("CLICKED");
    });
 });

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
 $btn.click(function () { //for mouseover--> $btn.on('mouseover', function () {
    console.log('clicked');
 });

// append dynamic button to the dynamic container
$div.append($btn);

// add the dynamically created element(s) to a static element
$("#box").append($div);

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


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

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

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) {
        alert("CLICKED");
    });
 });

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);
myElement.append('body');


function goToGoogle(event){
    window.location.replace("http://www.google.com");
}

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

_x000D_
_x000D_
var body = $("body");_x000D_
var btns = $("button");_x000D_
var btnB = $("<button>B</button>");_x000D_
// `<button>B</button>` is not yet in the document._x000D_
// Thus, `$("button")` gives `[<button>A</button>]`._x000D_
// Only `<button>A</button>` gets a click listener._x000D_
btns.on("click", function () {_x000D_
  console.log(this);_x000D_
});_x000D_
// Too late for `<button>B</button>`..._x000D_
body.append(btnB);
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<button>A</button>
_x000D_
_x000D_
_x000D_

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

_x000D_
_x000D_
var body = $("body");_x000D_
var btnB = $("<button>B</button>");_x000D_
var btnC = $("<button>C</button>");_x000D_
// Listen to all clicks and_x000D_
// check if the source element_x000D_
// is a `<button></button>`._x000D_
body.on("click", function (ev) {_x000D_
  if ($(ev.target).is("button")) {_x000D_
    console.log(ev.target);_x000D_
  }_x000D_
});_x000D_
// Now you can add any number_x000D_
// of `<button></button>`._x000D_
body.append(btnB);_x000D_
body.append(btnC);
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<button>A</button>
_x000D_
_x000D_
_x000D_

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

_x000D_
_x000D_
var i = 11;_x000D_
var body = $("body");_x000D_
body.on("click", "button", function () {_x000D_
  var letter = (i++).toString(36).toUpperCase();_x000D_
  body.append($("<button>" + letter + "</button>"));_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<button>A</button>
_x000D_
_x000D_
_x000D_


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:

_x000D_
_x000D_
function handleDynamicElementEvent(event) {_x000D_
  console.log(event.type, this.value)_x000D_
}_x000D_
// create and attach event to dynamic element_x000D_
jQuery("<select>", {_x000D_
    html: $.map(Array(3), function(_, index) {_x000D_
      return new Option(index, index)_x000D_
    }),_x000D_
    on: {_x000D_
      change: handleDynamicElementEvent_x000D_
    }_x000D_
  })_x000D_
  .appendTo("body");
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">_x000D_
</script>
_x000D_
_x000D_
_x000D_


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
$("<select></select>")
    .append( /* Your <option>s */ )
    .hover(mouseOverHandler, mouseOutHandler)
    .appendTo( /* Wherever you need the select box */ )
;

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


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){
    eles.hover(function(){alert("gotcha!")});
}

$(document).ready(function(){
    addCallbacks($(".myEles"))
});

// ... add elements ...
addCallbacks($(".myNewElements"))

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

_x000D_
_x000D_
$(document).ready(function(){_x000D_
  //Particular Parent chield click_x000D_
  $(".buttons").on("click","button",function(){_x000D_
    alert("Clicked");_x000D_
  });  _x000D_
  _x000D_
  //Dynamic event bind on button class  _x000D_
  $(document).on("click",".button",function(){_x000D_
    alert("Dymamic Clicked");_x000D_
  });_x000D_
  $("input").addClass("button");  _x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
<div class="buttons">_x000D_
  <input type="button" value="1">_x000D_
  <button>2</button>_x000D_
  <input type="text">_x000D_
  <button>3</button>  _x000D_
  <input type="button" value="5">  _x000D_
  </div>_x000D_
<button>6</button>
_x000D_
_x000D_
_x000D_


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(){} );

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);
myElement.append('body');


function goToGoogle(event){
    window.location.replace("http://www.google.com");
}

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){
    console.log($(this).text());
});

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){
    console.log($(this).text());
});

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.


Use the .on() method of jQuery http://api.jquery.com/on/ to attach event handlers to live element.

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


Bind the event to a parent which already exists:

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

Use the .on() method of jQuery http://api.jquery.com/on/ to attach event handlers to live element.

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


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
});

Try like this way -

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

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.

_x000D_
_x000D_
var iterations = 4;_x000D_
var button;_x000D_
var body = document.querySelector("body");_x000D_
_x000D_
for (var i = 0; i < iterations; i++) {_x000D_
    button = document.createElement("button");_x000D_
    button.classList.add("my-button");_x000D_
    button.appendChild(document.createTextNode(i));_x000D_
    button.addEventListener("click", myButtonWasClicked);_x000D_
    body.appendChild(button);_x000D_
}_x000D_
_x000D_
function myButtonWasClicked(e) {_x000D_
    console.log(e.target); //access to this specific button_x000D_
}
_x000D_
_x000D_
_x000D_


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

document.addEventListener('click', function (e) {
    if (hasClass(e.target, 'bu')) {
        // .bu clicked
        // Do your thing
    } else if (hasClass(e.target, '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);
}

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

_x000D_
_x000D_
var body = $("body");_x000D_
var btns = $("button");_x000D_
var btnB = $("<button>B</button>");_x000D_
// `<button>B</button>` is not yet in the document._x000D_
// Thus, `$("button")` gives `[<button>A</button>]`._x000D_
// Only `<button>A</button>` gets a click listener._x000D_
btns.on("click", function () {_x000D_
  console.log(this);_x000D_
});_x000D_
// Too late for `<button>B</button>`..._x000D_
body.append(btnB);
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<button>A</button>
_x000D_
_x000D_
_x000D_

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

_x000D_
_x000D_
var body = $("body");_x000D_
var btnB = $("<button>B</button>");_x000D_
var btnC = $("<button>C</button>");_x000D_
// Listen to all clicks and_x000D_
// check if the source element_x000D_
// is a `<button></button>`._x000D_
body.on("click", function (ev) {_x000D_
  if ($(ev.target).is("button")) {_x000D_
    console.log(ev.target);_x000D_
  }_x000D_
});_x000D_
// Now you can add any number_x000D_
// of `<button></button>`._x000D_
body.append(btnB);_x000D_
body.append(btnC);
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<button>A</button>
_x000D_
_x000D_
_x000D_

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

_x000D_
_x000D_
var i = 11;_x000D_
var body = $("body");_x000D_
body.on("click", "button", function () {_x000D_
  var letter = (i++).toString(36).toUpperCase();_x000D_
  body.append($("<button>" + letter + "</button>"));_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<button>A</button>
_x000D_
_x000D_
_x000D_


you could use

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

or

$('.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


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" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Untitled Document</title>
    </head>

    <body>
        <script src="http://code.jquery.com/jquery-latest.js"></script>
        <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js"></script>

        <input type="button" id="theButton" value="Click" />
        <script type="text/javascript">
            $(document).ready(function()
                {
                    $('.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'
                                                                                                     });
                    $('#theButton').click(function()
                    {
                        $dialog.dialog('open');
                        return('false');
                    });
                    $('#CUSTOM').click(function(){
                        //$('#container').append('<input type="button" value="clickmee" class="FOO" /></br>');
                        var button = document.createElement("input");
                        button.setAttribute('class','FOO');
                        button.setAttribute('type','button');
                        button.setAttribute('value','CLICKMEE');
                        $('#container').append(button);
                    });
                    /* $('#FOO').click(function(){
                                                     alert("It Works!");
                                                 }); */
            });
        </script>
    </body>
</html>

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
 $btn.click(function () { //for mouseover--> $btn.on('mouseover', function () {
    console.log('clicked');
 });

// append dynamic button to the dynamic container
$div.append($btn);

// add the dynamically created element(s) to a static element
$("#box").append($div);

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


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:

_x000D_
_x000D_
function handleDynamicElementEvent(event) {_x000D_
  console.log(event.type, this.value)_x000D_
}_x000D_
// create and attach event to dynamic element_x000D_
jQuery("<select>", {_x000D_
    html: $.map(Array(3), function(_, index) {_x000D_
      return new Option(index, index)_x000D_
    }),_x000D_
    on: {_x000D_
      change: handleDynamicElementEvent_x000D_
    }_x000D_
  })_x000D_
  .appendTo("body");
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">_x000D_
</script>
_x000D_
_x000D_
_x000D_


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

document.addEventListener('click', function (e) {
    if (hasClass(e.target, 'bu')) {
        // .bu clicked
        // Do your thing
    } else if (hasClass(e.target, '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);
}

you could use

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

or

$('.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


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
$("<select></select>")
    .append( /* Your <option>s */ )
    .hover(mouseOverHandler, mouseOutHandler)
    .appendTo( /* Wherever you need the select box */ )
;

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){
    console.log($(this).text());
});

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){
    console.log($(this).text());
});

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.


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
});

And HTML

<div class="wrapper-class">
    <button class="selector-class">
      Click Me!
    </button>
</div>    

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


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" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Untitled Document</title>
    </head>

    <body>
        <script src="http://code.jquery.com/jquery-latest.js"></script>
        <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js"></script>

        <input type="button" id="theButton" value="Click" />
        <script type="text/javascript">
            $(document).ready(function()
                {
                    $('.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'
                                                                                                     });
                    $('#theButton').click(function()
                    {
                        $dialog.dialog('open');
                        return('false');
                    });
                    $('#CUSTOM').click(function(){
                        //$('#container').append('<input type="button" value="clickmee" class="FOO" /></br>');
                        var button = document.createElement("input");
                        button.setAttribute('class','FOO');
                        button.setAttribute('type','button');
                        button.setAttribute('value','CLICKMEE');
                        $('#container').append(button);
                    });
                    /* $('#FOO').click(function(){
                                                     alert("It Works!");
                                                 }); */
            });
        </script>
    </body>
</html>

<html>
    <head>
        <title>HTML Document</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
    </head>

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

        <script>
            jQuery(document).ready(function($){
                $(document).on('mouseover', '#hover-id', function(){
                    $(this).css('color','yellowgreen');
                });

                $(document).on('mouseout', '#hover-id', function(){
                    $(this).css('color','black');
                });
            });
        </script>
    </body>
</html>

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
});

And HTML

<div class="wrapper-class">
    <button class="selector-class">
      Click Me!
    </button>
</div>    

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


Bind the event to a parent which already exists:

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

<html>
    <head>
        <title>HTML Document</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
    </head>

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

        <script>
            jQuery(document).ready(function($){
                $(document).on('mouseover', '#hover-id', function(){
                    $(this).css('color','yellowgreen');
                });

                $(document).on('mouseout', '#hover-id', function(){
                    $(this).css('color','black');
                });
            });
        </script>
    </body>
</html>

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(){} );

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){
    eles.hover(function(){alert("gotcha!")});
}

$(document).ready(function(){
    addCallbacks($(".myEles"))
});

// ... add elements ...
addCallbacks($(".myNewElements"))

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
});

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

_x000D_
_x000D_
$(document).ready(function(){_x000D_
  //Particular Parent chield click_x000D_
  $(".buttons").on("click","button",function(){_x000D_
    alert("Clicked");_x000D_
  });  _x000D_
  _x000D_
  //Dynamic event bind on button class  _x000D_
  $(document).on("click",".button",function(){_x000D_
    alert("Dymamic Clicked");_x000D_
  });_x000D_
  $("input").addClass("button");  _x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>_x000D_
<div class="buttons">_x000D_
  <input type="button" value="1">_x000D_
  <button>2</button>_x000D_
  <input type="text">_x000D_
  <button>3</button>  _x000D_
  <input type="button" value="5">  _x000D_
  </div>_x000D_
<button>6</button>
_x000D_
_x000D_
_x000D_


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){
    eles.hover(function(){alert("gotcha!")});
}

$(document).ready(function(){
    addCallbacks($(".myEles"))
});

// ... add elements ...
addCallbacks($(".myNewElements"))

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.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to events

onKeyDown event not working on divs in React Detect click outside Angular component Angular 2 Hover event Global Events in Angular How to fire an event when v-model changes? Passing string parameter in JavaScript function Capture close event on Bootstrap Modal AngularJs event to call after content is loaded Remove All Event Listeners of Specific Type Jquery .on('scroll') not firing the event while scrolling

Examples related to unobtrusive-javascript

window.onload vs $(document).ready() Event binding on dynamically created elements?