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

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

This question already has an answer here:

Event binding on dynamically created elements?

23 answers

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 = $(‘

‘)
.css({
‘display’ : ‘inline’,
‘padding’ : ‘0px 2px 2px 0px’,
‘cursor’ : ‘pointer’
}).append($(‘‘).attr({
//’href’ : Share.serializeJson(data),
‘target’ : ‘_blank’,
‘rel’ : ‘nofollow’
}).append($(‘‘).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 :(“);
});

Related:  AngularJS - How to use ng-if without HTML element

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

Solutions/Answers:

Solution 1:

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:

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.

Related:  Expected a spy, but got Function

Solution 3:

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:

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/

Related:  Nested JSON: How to add (push) new items to an object?

Solution 5:

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:

On event

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

Or add the event after append