I create an element using Jquery
and give it the class .book
:
jQuery('<div/>', {
name: "my name",
class: 'book',
text: 'Bookmark',
}).appendTo('body');
then i want to do something when that class is clicked, so naturally I wrote a quick and easy:
$('.book').click(function(){
alert('I have been clicked');
});
That works
what does not work, is if I have it add those elements on click. so the following does not work:
var bms = 0;
$('button').click(function(){
bms += 1;
jQuery('<div/>', {
name: bms,
class: 'book',
text: 'Bookmark ' + bms
}).appendTo('body');
});
$('.book').click(function(){
alert('I have been clicked');
});
why does this happen, and how can I fix this?
Jsfiddle
another thing:
Also, if I already have a div with the class .book
in my body, the click event will work on that one, but not any of the appended div
s. here is another jsfiddle to show that
I create an element using Jquery
and give it the class .book
:
jQuery('<div/>', {
name: "my name",
class: 'book',
text: 'Bookmark',
}).appendTo('body');
then i want to do something when that class is clicked, so naturally I wrote a quick and easy:
$('.book').click(function(){
alert('I have been clicked');
});
That works
what does not work, is if I have it add those elements on click. so the following does not work:
var bms = 0;
$('button').click(function(){
bms += 1;
jQuery('<div/>', {
name: bms,
class: 'book',
text: 'Bookmark ' + bms
}).appendTo('body');
});
$('.book').click(function(){
alert('I have been clicked');
});
why does this happen, and how can I fix this?
Jsfiddle
another thing:
Also, if I already have a div with the class .book
in my body, the click event will work on that one, but not any of the appended div
s. here is another jsfiddle to show that
- Look up event handling with dynamically added elements. – Brad M Commented Jul 24, 2013 at 20:03
-
At the time
$('.book').click(...
event handler assignment happens, there is no DOM elements withclass="book"
. See @KyleK answer for the way to assign events to current and future items. – Igor Commented Jul 24, 2013 at 20:05
4 Answers
Reset to default 7You have to delegate to the newly created elements, like so...
Just replace this...
$('.book').click(function(){
alert('I have been clicked');
});
With this....
$(document).on('click','.book', function(){
alert('I have been clicked');
});
Those are direct binding, wich are not working on dynamicly added elements like .book
.
You can use .on()
to bind event on dynamicly added elements like that:
$('body').on('click', '.book' ,function(){
alert('I have been clicked');
});
Where body will be the closest static element. Those type of binding are called delegated event.
Fiddle : http://jsfiddle/3MpcG/2/
Or you can bind a direct event on the element when creating it.
.appendTo('body').click(function(){
alert('I have been clicked');
});
Fiddle : http://jsfiddle/3MpcG/3/
Both have advantage and disadvantage, you can read them on jQuery .on() docs page.
Your problem is you're attaching an event to an element that isn't ready to receive that event. You should attach the event to a parent element, then you can filter for the .book
. This way it doesn't matter when your click able element gets added, it will work. This is called event delegation. You're delegating the task of handling the event to another element.
HTML:
<body>
<button>Click here to add book.</button>
</body>
And your JS:
$(document).on("click", ".book", function() {
alert('it works!');
});
var bms = 0;
$('button').click(function(){
bms += 1;
jQuery('<div/>', {
name: bms,
class: 'book',
text: 'Bookmark ' + bms
}).appendTo('body');
});
Also when doing this, don't attach it to a parent that's too high up the tree. You want to attach it to the nearest possible parent element. We don't need to have a click event on something like document
because it's a good idea to be specific of which elements will get this event. Attaching it to document
will mean that any element, that has the class of .book
, will be click able and respond to the same code. If you want to have different functionality in different buttons, you can't, because they're all responding to the same code attached to document
.
If any of these not working then wrap the click event with setTimeout function.
setTimeout(function () {
$(document).on("click", ".book", function() {
alert('it works!');
});
), 500};