Reputation: 1190
HTML:
<h2>CHECK AS MANY AS YOU CAN</h2>
<form id="boxone">
</form>
JS:
$boxone = $("#boxone");
$boxone.html('<input type="checkbox" class="fourthboxes">');
$fourthboxes = $(".fourthboxes");
for(var i=0; i <341; i++) {
$fourthboxes.clone(true, true).appendTo($boxone);
}
$fourthboxes.change(function() {
alert('yo');
});
The rest of the checkboxes don't alert when I click on them, only the original one does I even tried $fourthboxes.on('click'... instead and still nothing. I took a look at this question and tried the solution but it didn't work.
jQuery clone() not cloning event bindings, even with on()
Upvotes: 1
Views: 384
Reputation: 1254
When you clone
an object, only the objects are cloned. And not their events. Because the events are bound to the original object (based on the jQuery selector used) before creating the clone.
As @trincot mentioned in his answer, you need to have an event at the document level.
For eg. Let's say my DOM contains three input checkboxes
<input type="checkbox" class="fourthboxes">
<input type="checkbox" class="fourthboxes">
<input type="checkbox" class="fourthboxes">
Now when you bind events using the jQuery selector like this,
$(".fourthboxes").change(function() {
alert('yo');
});
Things to note, is that this jQuery selector returns an array of DOM elements which are present on the page, at that instant of time. And then the onchange event is registered on each of them. It is equivalent to binding the event to each of the existing DOM.(In this case, three checkboxes)
Upvotes: 0
Reputation: 349999
Use .on()
:
$(document).on('change', '.fourthboxes', function() {
alert('yo');
});
This makes your event handler work for current elements, but also future added elements, that match the .fourthboxes
selector. This uses the principle of delegated events.
From the documentation:
When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles the event from the event target up to the element where the handler is attached (i.e., innermost to outermost element) and runs the handler for any elements along that path matching the selector.
Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.
Upvotes: 2
Reputation: 1744
Since you assign $(".fourthboxes")
to the variable $fourthboxes
before you add the 340 other checkboxes, the variable still holds only that one checkbox when you add the change-function.
Put the change-function in front of the for-loop and everything works as expected.
Upvotes: 1
Reputation: 337560
The issue is because although you use clone(true, true)
you're cloning the elements before you add the change
event handler to them. You just need to swap the logic around:
$boxone = $("#boxone");
$boxone.html('<input type="checkbox" class="fourthboxes">');
$fourthboxes = $(".fourthboxes");
$fourthboxes.change(function() {
alert('yo');
});
for(var i=0; i <341; i++) {
$fourthboxes.clone(true, true).appendTo($boxone);
}
However, it would be much better to use a single delegated event handler, like this:
var $boxone = $("#boxone").on('change', '.fourthboxes', function() {
alert('yo');
});
var $fourthboxes = $('<input type="checkbox" class="fourthboxes">').appendTo('#boxone');
for (var i = 0; i < 341; i++) {
$fourthboxes.clone().appendTo($boxone);
}
Upvotes: 2
Reputation: 207501
It only selects the original because you never select the new elements. The selector only has the original, it is not a live collection. So you need to reselect them.
$(".fourthboxes").on("change", ...)
You can use event delegation so you are not selecting all the checkboxes. Listen for the change event on the form.
$("#boxone").on("change", ".fourthboxes", function(){});
Upvotes: 0