Reputation: 12531
In jQuery, you can add an event listener to the document
using .on()
with a selector as the 2nd argument to listen to all events sent to specific elements, even if the HTML is dynamically changes.
It looks something like this:
$(document).on('change', "input:checkbox", onCheckboxChange);
How can I do the same thing in pure modern JavaScript which works even if HTML is dynamically changed?
I understand I could do something like document.querySelector('input:checkbox')
and apply an event listener to each individual element, but if a new input:checkbox
is added, then it will not have the same event listener that the other input's have.
Upvotes: 2
Views: 1972
Reputation: 1075537
You'd attach the listener to document
(that part's the same) accepting the event parameter (let's call it e
) and use Element#closest
on e.target
to determine whether the event passed through an element matching a selector:
document.addEventListener("change", function(e) {
var target = e.target.closest("input[type=checkbox]");
if (target) {
// It matches
console.log("change", target.checked);
}
});
Live Example (including adding a matching element after the fact):
document.addEventListener("change", function(e) {
var target = e.target.closest("input[type=checkbox]");
if (target) {
// It matches
console.log("change", target.checked);
}
});
setTimeout(function() {
document.body.insertAdjacentHTML(
"beforeend",
"<div><label><input type='checkbox'> Or tick me");
}, 800);
<div>
<label>
<input type="checkbox"> Tick me
</label>
</div>
Element#closest
is fairly new, but present in all modern browsers (so, not IE). You can polyfill it on IE, though; see the linked MDN article for a polyfill.
You can give yourself a utility function that does effectively what jQuery's delegating version of on
does quite easily:
function addHandler(element, selector, eventName, handler) {
if (typeof eventName === "undefined") {
// No selector, swap things around
eventName = selector;
selector = undefined;
}
element.addEventListener(eventName, function(e) {
var currentTarget = e.currentTarget;
if (selector) {
currentTarget = e.target.closest(selector);
if (!currentTarget) {
// Not a match, ignore
return;
}
}
// Note we use `currentTarget` as this during the call
// Sadly, `currentTarget` on the actual event object is
// read-only. We could create a synthetic event object
// like jQuery does and set it on that instead.
// I didn't do that here, but it's easy enough.
return handler.call(currentTarget, e);
});
return element;
}
// Usage
addHandler(document, "input[type=checkbox]", "change", function(e) {
console.log("changed", this.checked);
});
setTimeout(function() {
document.body.insertAdjacentHTML(
"beforeend",
"<div><label><input type='checkbox'> Or tick me");
}, 800);
<div>
<label>
<input type="checkbox"> Tick me
</label>
</div>
Upvotes: 4
Reputation: 306
First I am creating a checkbox and then appending it to Dom And them adding event listener to it by its Id.
var checkbox = document.createElement('input');
checkbox.type = "checkbox";
checkbox.name = "name";
checkbox.value = "value";
checkbox.id = "id";
document.body.appendChild(checkbox);
var abc = document.getElementById('id');
abc.addEventListener("click", function () {
alert('click');
});
Upvotes: -1