I'm trying to build and learn native javascript event delegation
(not sure though) like this
function clicked(d) {
d.innerText = "clicked";
}
document.addEventListener('click', function() {
var foos = Array.from(document.getElementsByClassName('foo'));
foos.forEach(function(elm, i) {
elm.addEventListener('click', function() {
clicked(elm);
});
});
})
document.body.innerHTML = `<div class="foo"></div><div class="foo"></div><div class="foo"></div><div class="foo"></div>`;
.foo {
height: 100px;
width: 100px;
float: left;
border: 1px solid green;
}
Why is it only working after the 2nd click forward?
I can change my addEventListener code block above with jQuery on
method to get it to work but i just want to know how to make my code above act similar.
Event delegation uses event bubbling and the event.target
property to process an event for several child elements with a single event handler attached to their parent (see this explanation by Andrew Tetlaw and other examples in this blog post by David Walsh).
In your case, you don't need to add an event handler to each foo
div since the click event is handled at the document level. You can simply check if the target of the click event has the foo
class and pass that target element to the clicked
function.
function clicked(d) {
d.innerText = "clicked";
}
document.addEventListener('click', function(e) {
if (e.target.className === "foo") {
clicked(e.target);
}
});
document.body.innerHTML = '<div class="foo"></div><div class="foo"></div><div class="foo"></div><div class="foo"></div>';
.foo {
height: 100px;
width: 100px;
float: left;
border: 1px solid green;
}