0

I have added an on click event on a container element like so,

<li>
    <div id="python-icon" class="container">
        <img src="utilities/python-logo.svg"/>
        <span class="ml-2"> <strong>  Python </strong> </span>
    </div>
</li>




document.getElementById("python-icon").addEventListener('click', e => {
    debugger;
    if (current_state !== e.target.id){
        current_state = e.target.id;
        ...
    }

});

The problem I am having after adding a break point, that this on click events will hit the break point if I click the child elements, i.e. the <img> or the <span>, however I wanted to enter this area if the on click event for the container was selected. Because the child elements enter, "e.target.id" evaluates as an empty string, breaking the logic I have entered.

Why are the child elements being hit, when I clearly in the code have used "document.getElementById" on the container, which is where I want this logic to be applied on, the container.

I have a container when an 'on_click' and all of the behaviour is attached to that container. If I click on the container, and it was registered on the child, I would like the child to propogate the event to the container, so that I can grab the "id" of the container, and not that of the child.

For example, if I wanted an extreme hack I would want to do something like this.

document.getElementById("python-icon").addEventListener('click', e => {
        let comparer = e.target.id;
        if (e.target.localName === "img" || e.target.localName === "span"){
            comparer = e.target.parentElement.id;
        }
        if (current_state !== comparer){
            current_state = comparer
         ...
        }

});

but of course that feels, wrong :(

J.Doe
  • 173
  • 1
  • 7
  • 1
    Event bubbling. You click on the image and event propagates to the top of the document. – Vladislav Khazipov Nov 24 '19 at 06:37
  • @VladislavKhazipov Sounds like what I want to happen, but the event being passed at the moment is being regitered as the child. i.e. e.target == child of the container I clicked. I want the event to be passed through on the on_click such that e.target is the container, not the child element. The container is on top, so I thought this would happen. – J.Doe Nov 24 '19 at 08:43

2 Answers2

0

Add click to your child element to prevent parent containers function form being called

document.getElementById('child').addEventListener('click',function (event){
   event.stopPropagation();
});

event.stopPropagation() will stop the bubbling upto parent containers event

Sameer
  • 705
  • 10
  • 25
0

IF I understood correctly then you can compare the target and currentTarget properties from the Event to determine if the element that was click was designated as the actual target itself or a child.

I added the border so that you can clearly see the element that needs to be clicked.

<ul>
    <li>
        <div id="python-icon" class="container" style='border:5px solid red;width:50%'>
            <img src="/images/css/svg/upload.svg" width=32px/>
            <span class="ml-2"> <strong>  Python </strong> </span>
        </div>
    </li>
</ul>
<script>
    document.getElementById("python-icon").addEventListener('click', e => {
        if( e.target==e.currentTarget ){
            alert(e.target)
        }else{
            console.info(e.target)
        }
    });
</script>

   document.getElementById("python-icon").addEventListener('click', e => {
    if( e.target==e.currentTarget ){
     alert(e.target)
    }else{
     console.info(e.target)
    }
   });
  <ul>
   <li>
    <div id="python-icon" class="container" style='border:5px solid red;width:50%'>
     <img src="/images/css/svg/upload.svg" width=32px/>
     <span class="ml-2"> <strong>  Python </strong> </span>
    </div>
   </li>
  </ul>

Ok, looks like I misunderstood your meaning - perhaps this is closer? The above allows you to distinguish between the desired container receiving the click or the child elements receiving the click which appears to be what you wanted?? Afterall, if the goal is to launch the debugger if, and only if, the element that is clicked happens to be the container (id="python-icon") the you assign the debug routines where the alert would be..or is.

Though the comment so that I can grab the "id" of the container, and not that of the child is confusing - you already know the ID of the container...

    document.getElementById( 'python-icon' ).addEventListener('click', function( e ){
  const getparent=function(e){
   let n=e.target;
   while( n!=e.currentTarget )n=n.parentNode;
   return n;
  }
  let directhit=e.target==e.currentTarget;
  let id=getparent(e).id;
  console.info('Event [%s]\nRegistered on [%o]\nTriggered by [%o]\nDirect hit: %s\nThe ID: %s', e.type, e.currentTarget, e.target, directhit, id );
    });
<ul>
    <li>
        <div id="python-icon" class="container" style='border:5px solid red;width:50%'>
            <img src="/images/css/svg/upload.svg" width=32px/>
            <span class="ml-2"> <strong>  Python </strong> </span>
        </div>
    </li>
</ul>
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • I don't think this answers my question. I have a container when an 'on_click' and all of the behaviour is attached to that container. If I click on the container, and it was registered on the child, I would like the child to propogate the event to the container, so that I can grab the "id" of the container, and not that of the child. – J.Doe Nov 24 '19 at 08:23