Attaching click event to a JQuery object not yet added to the DOM

JavascriptJqueryOnclickJquery Events

Javascript Problem Overview


I've been having a lot of trouble attaching the click event to a JQuery object before adding it to the DOM.

Basically I have this button that my function returns, then I append it to the DOM. What I want is to return the button with its own click handler. I don't want to select it from the DOM to attach the handler.

My code is this:

createMyButton = function(data) {

  var button = $('<div id="my-button"></div>')
    .css({
       'display' : 'inline',
       'padding' : '0px 2px 2px 0px',
       'cursor' : 'pointer'
     }).append($('<a>').attr({
       //'href' : Share.serializeJson(data),
       'target' : '_blank',
       'rel' : 'nofollow'
     }).append($('<image src="css/images/Facebook-icon.png">').css({
       "padding-top" : "0px",
       "margin-top" : "0px",
       "margin-bottom" : "0px"
     })));
	
     button.click(function () {
        console.log("asdfasdf");
     });

     return button;		
}

The button that is return is unable to catch the click event. However, if I do this (after the button is added to the DOM):

$('#my-button').click(function () {
    console.log("yeahhhh!!! but this doesn't work for me :(");
});

It works... but not for me, not what I want.

It seems to be related to the fact that the object is not yet a part of the DOM.

Oh! By the way, I'm working with OpenLayers, and the DOM object that I'm appending the button to is an OpenLayers.FramedCloud (Which is not yet a part of the DOM but will be once a couple of events are triggered.)

Javascript Solutions


Solution 1 - Javascript

Use this. You can replace body with any parent element that exists on dom ready

$('body').on('click', '#my-button', function () {
     console.log("yeahhhh!!! but this doesn't work for me :(");
});

Look here http://api.jquery.com/on/ for more info on how to use on() as it replaces live() as of 1.7+.

Below lists which version you should be using

>$(selector).live(events, data, handler); // jQuery 1.3+ > >$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+ > >$(document).on(events, selector, data, handler); // jQuery 1.7+

Solution 2 - Javascript

I am really surprised that no one has posted this yet

$(document).on('click','#my-butt', function(){
   console.log('document is always there');
}) 

If you are unsure about what elements are going to be on that page at that time just attach it to document.

Note: this is sub-optimal from performance perspective - to get maximum speed one should try to attach to the nearest parent of element that is going to be inserted.

Solution 3 - Javascript

Try this.... Replace body with parent selector

$('body').on('click', '#my-button', function () {
    console.log("yeahhhh!!! but this doesn't work for me :(");
});

Solution 4 - Javascript

Try:

$('body').on({
    hover: function() {
        console.log("yeahhhh!!! but this doesn't work for me :(");
    },
    click: function() {
        console.log("yeahhhh!!! but this doesn't work for me :(");
    }
},'#my-button');

jsfiddle example.

When using .on() and binding to a dynamic element, you need to refer to an element that already exists on the page (like body in the example). If you can use a more specific element that would improve performance.

> 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(). > To ensure the elements are present and can be selected, perform event > binding inside a document ready handler for elements that are in the > HTML markup on the page. If new HTML is being injected into the page, > select the elements and attach event handlers after the new HTML is > placed into the page. Or, use delegated events to attach an event > handler, as described next.

Src: http://api.jquery.com/on/

Solution 5 - Javascript

You have to append it. Create the element with:

var $div = $("<div>my div</div>");
$div.click(function(){alert("clicked")})
return $div;

Then if you append it will work.

Take a look at your example here and a simple version here.

Solution 6 - Javascript

Complement of information for those people who use .on() to listen to events bound on inputs inside lately loaded table cells; I managed to bind event handlers to such table cells by using delegate(), but .on() wouldn't work.

I bound the table id to .delegate() and used a selector that describes the inputs.

e.g.

HTML

<table id="#mytable">
  <!-- These three lines below were loaded post-DOM creation time, using a live callback for example -->
  <tr><td><input name="qty_001" /></td></tr>
  <tr><td><input name="qty_002" /></td></tr>
  <tr><td><input name="qty_003" /></td></tr>
</table>

jQuery

$('#mytable').delegate('click', 'name^=["qty_"]', function() {
    console.log("you clicked cell #" . $(this).attr("name"));
});

Solution 7 - Javascript

Does using .live work for you?

$("#my-button").live("click", function(){ alert("yay!"); }); 

http://api.jquery.com/live/

EDIT

As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().

http://api.jquery.com/on/

Solution 8 - Javascript

On event

$('#my-button').on('click', function () {
    console.log("yeahhhh!!! but this doesn't work for me :(");
});

Or add the event after append

Solution 9 - Javascript

jQuery .on method is used to bind events even without the presence of element on page load. Here is the link It is used in this way:

 $("#dataTable tbody tr").on("click", function(event){
 	alert($(this).text());
 });

Before jquery 1.7, .live() method was used, but it is deprecated now.

Solution 10 - Javascript

Maybe bind() would help:

button.bind('click', function() {
  alert('User clicked');
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondanielrvtView Question on Stackoverflow
Solution 1 - Javascriptwirey00View Answer on Stackoverflow
Solution 2 - JavascriptMatas VaitkeviciusView Answer on Stackoverflow
Solution 3 - JavascriptVinsView Answer on Stackoverflow
Solution 4 - Javascriptj08691View Answer on Stackoverflow
Solution 5 - JavascriptMarco AlloriView Answer on Stackoverflow
Solution 6 - JavascriptFabien HaddadiView Answer on Stackoverflow
Solution 7 - JavascriptPsychoDUCKView Answer on Stackoverflow
Solution 8 - JavascriptJorgeView Answer on Stackoverflow
Solution 9 - JavascriptNishu TayalView Answer on Stackoverflow
Solution 10 - JavascriptZEROView Answer on Stackoverflow