'Javascript get "clicked" element addEventListener
I know I can grab the element of an individual ID.
Anyway I can attach a listener to the parent div and pass the ID of the individual span that was clicked?
<div id = "divId">
<span id="one"></span>
<span id="two"> </span>
</div>
JS
document.getElementById("two").addEventListener("click", someFunction);
Solution 1:[1]
You can use the event object and access its target property
document.getElementById("divId").addEventListener("click", someFunction);
function someFunction(event) {
console.log(event.target.id);
}
<div id="divId">
<span id="one">one</span>
<span id="two"> two</span>
</div>
Solution 2:[2]
If the user clicked on a node that was a child of the element the user wanted to test e.target will be a different node. The sensible way to check this nowadays is to listen at the document level and iterate the path (or use some delegation library, of which there are many):
Add one event listener to the document:
const isOnId = (path,id) => path.some(element => element.id === id);
document.addEventListener('click',function(e) {
if(isOnId(e.path,'two')) {
//you clicked on or in element with an id two
} else {
//you clicked on something else
}
});
Solution 3:[3]
Adam's answer is correct and saves a lot of headaches. However there's a better and easiest way to acieve this. Please check this answer
Makes use of Event.currentTarget and it goes like this:
<ul>
<li class="list_item" data-mydata="hello there!">
<img src="..." alt="" width="50", height="50">
</li>
<li class="list_item" data-mydata="hello world">
<img src="..." alt="" width="50", height="50">
</li>
</ul>
<script>
const items = document.querySelectorAll(".list_item");
items.forEach(node => {
node.addEventListener("click", e => {
let myvalue = e.currentTarget.dataset.mydata;
console.log(myvalue); //hello there! || hello world It depends on which element the user has clicked
})
})
</script>
I hope this is useful
Solution 4:[4]
Since I do not have enough credits to comment, adding a new answer.
Unlike the answer shared by @CubeInTheBox, I think leveraging the concept of event capturing/bubbling for the respective element makes for a better implementation rather than adding an event listener to each of the target elements. For the example shared above, the alternative would be:
<ul>
<li class="list_item" data-mydata="hello there!">
<img src="..." alt="" width="50", height="50">
</li>
<li class="list_item" data-mydata="hello world">
<img src="..." alt="" width="50", height="50">
</li>
</ul>
<script>
const parentElement = document.querySelector('ul');
parentElement.addEventListener('click', e => {
// If you want to add the listener on li alone and not on image
if (e.target.className === 'list_item') {
const myvalue = e.target.dataset.mydata;
console.log(myvalue);
}
});
</script>
NOTE that e.currentTarget wouldn’t work for this case, as it would return the parent ul to which the event is bound.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Adam |
| Solution 3 | CubeInTheBox |
| Solution 4 | ManjuRam |
