Attaching click event to a JQuery object not yet added to the DOM
JavascriptJqueryOnclickJquery EventsJavascript 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');
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.
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.
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!"); });
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().
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');
});