Reputation: 21739
$('.sss').click(function() {
$("#a"+id).html("<textarea id=\"txt\" rows=\"8\" cols=\"75\">fddscx</textarea> <br />"+
"<input type=\"button\" id=\"xxx\" value=\"Do smth button\" class=\"submit_button\" />");
});
$('#xxx').click(function() {
alert("button happened");
});
I click something which has class sss
. Then a button appears which has id xxx
. Why doesn't it give me an alert when I click it?
Thank you.
Upvotes: 3
Views: 221
Reputation: 105029
This won't work because your button was dynamically added to the document and you added click event to an element that doesn't exist yet. It will exist after you click the .sss
element.
You have two options to solve your problem:
live()
/.delegate()
instead of .click()
Instead of using .click()
you can use .live()
which binds events to existing as well as future elements (but don't think of it as a silver bullet and start using it everywhere). This actually binds a click event to document
and checks whether actual click event was fired on an element that matches selector. This means that live()
(and .delegate()
as well) functionality gets executed much more frequently doing all these checks. So use it wisely:
$('#xxx').live("click", function() {
alert("button happened");
})
The best and correct way would of course be to bind your event after you've created your element. And that's in the click event of the .sss
element:
$('.sss').click(function() {
$("#a"+id).html("<textarea id=\"txt\" rows=\"8\" cols=\"75\">fddscx</textarea> <br />"+
"<input type=\"button\" id=\"xxx\" value=\"Do smth button\" class=\"submit_button\" />");
$('#xxx').click(function() {
alert("button happened");
})
})
I suggest you use the second solution.
.click()
and .live()
both have to execute jQuery selector first then bind the event (.click()
directly to selected elements, .live()
to documement
and saves jQuery selector along with it no matter whether any elements with that selector existed or not).
.delegate()
selects one elements to which it will bind the event. Similarly to .live()
it also saved selector.
.click()
is the clear winner here, because it will execute directly on the element withou any overhead of selector matching.
.delegate()
and .live()
both have some overhead of selector matching. But the bigger problem is that imagine that user click all over the document (which is very common since user interacts regularly with clicks). Every single click is evaluated when .live()
has been used. And depending on the container selection of .delegate()
the same can be said. They both execute much much more events than they actually should be executed.
When a click happens, it gets bubbled up all the way to its container (be it document
r some other container associated with .delegate()
). Every click has to be evaluated whether target elements matches selector. If it does, jQuery also executes event handler provided along with .live()
or .delegate()
event binding.
Executing a jQuery selector once is still not that bad compared to evaluating selector eac time a user clicks something (whatever) in the document. Hence I find .live()
and .delegate()
event registration similar and should be avoided whenever possible.
Use direct event binding when possible. It is the fastest possible execution which usually happens much more often than event registration.
Upvotes: 2
Reputation: 78667
It does not work because you create the handler before the element is part of the dom. You should use .delegate on the container element. Delegate allows you to handle events for current and future elements.
An example in your case would be
function clickHandler(){
alert("button happened");
}
$('#someContainer').delegate('.sss', 'click' , clickHandler);
Upvotes: 3