For a research project, I am building a web tool to track users' interactions with specific elements that I need for later analysis.
Often, I have interactable containers that contain graphics or text elements, sometimes both. For instance:
<div id="specific-interaction-id"> <!-- This id is what I want to track -->
<img id="img-id" src="path/to/img.png"/> <!-- But i am triggering either this... -->
<p> Some Text </p> <!--...or this -->
</div>
I style the container by its interaction-field
class and have a javascript function that logs all interactions based on the trackable
class. Now, I got two issues.
- For the tracking, I want to store the container's id for simplicity, as in such cases the
<img>
and<p>
belong together. However, mostclick
events, for example, are only recognised on child elements. - Because of this, the parents'
targetable
class is not triggering, denying any logging. Since I want the parents' id as a compound trackable element, I would like to avoid giving the children thetargetable
class to avoid ambiguity and redundancy.
I do get the general layering problem and it is logical that I rather hit the children than their parents. But is there an elegant way to always pass the parents' classes and id's to make the logging easier? Or is there an even simpler solution that I am not seeing?
Thanks in advance!
CodePudding user response:
You can delegate the click handler to the document. Then grab the clicked element and use closest to find the parent element's ID if it has the trackable class.
document.addEventListener("click",(e)=>{
let trackedEl = e.target.closest(".trackable");
if(trackedEl){
console.log(trackedEl.id)
}
});
<div id="specific-interaction-id"> <!-- This id is what I want to track -->
<img id="img-id" src="path/to/img.png"/> <!-- But i am triggering either this... -->
<p> Some Text </p> <!--...or this -->
</div>
CodePudding user response:
First of all, if your question is on javascript you should have showed us the corresponding code.
Now, if you have event listeners on parent and child elements you can handle this through propagation.
When an event is triggered there are three phases.
Capturing - It first goes up the tree of elements starting from the root up to the targeted element. This by default doesn't trigger anything
Target phase - It triggers the targeted element's event.
Bubbling - It goes back down the tree again all the way to the root. This phase does trigger the events of the parents.
Your parent's event should be triggering in the bubbling phase. First make sure that you set it correctly. Make it trigger an alert or something that makes you know if its happening.
You can also decide to trigger it in the capturing phase but I don't you need that.
Once you know for sure the event works it should be triggered when you click on its children. From there it is only a matter of adding the id to your list.
You can check this page to learn more about event propagation: https://javascript.info/bubbling-and-capturing
I think you might find exactly what you need in there.