Home > Enterprise >  JS event bubbling - How can I avoid the changing targets?
JS event bubbling - How can I avoid the changing targets?

Time:01-19

I have bound click eventListeners to an up and down vote button.

Problem: When I click on different parts of the button I get the corresponding element I clicked on and not the parent element which contains relevant information for further processing.

What I already tried: I already tried ev.stopPropagation(); but the behaviour remained the same.

Question: How can I solve this problem?

My example code

const commentVotes = document.querySelectorAll('.comment-votes');

commentVotes.forEach((row) => {
  const up = row.querySelector('.comment-vote-up');
  const down = row.querySelector('.comment-vote-down');            

  up.addEventListener('click', async (ev) => {    
    // ev.stopPropagation();
    const id = ev.target.getAttribute('data-item-id');
    console.log({"target": ev.target, "ID": id})
  });
  
  down.addEventListener('click', async (ev) => {
    // same as up
  })
});
.comment .comment-vote-box {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
}

.spacer {
  margin-right:10px;
}
<div >
  <div >
    
    <div >
      <button 
              data-item-id="11">
        <span >Like</span>
        <span>0</span>
      </button>
    </div>
    
    <div >
      <button 
              data-item-id="12">
        <span >Dislike</span>
        <span>1</span>
      </button>
    </div>
    
  </div>
</div><!-- comment -->

CodePudding user response:

Use the Event.currentTarget to get the attribute values from.

CodePudding user response:

ev.target: is the element within the bubbling that triggered the event. So exactly what you are describing.

ev.currentTarget: is the element to which you have bound the listener.

* ev = event

https://medium.com/@etherealm/currenttarget-vs-target-in-js-2f3fd3a543e5

const commentVotes = document.querySelectorAll('.comment-votes');

commentVotes.forEach((row) => {
  const up = row.querySelector('.comment-vote-up');
  const down = row.querySelector('.comment-vote-down');            

  up.addEventListener('click', async (ev) => {    
    // ev.stopPropagation();
    const id = ev.currentTarget.getAttribute('data-item-id');
    console.log({"target": ev.target, "currentTarget": ev.currentTarget, "ID": id})
  });
  
  down.addEventListener('click', async (ev) => {
    // same as up
  })
});
.comment .comment-vote-box {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
}

.spacer {
  margin-right:10px;
}
<div >
  <div >
    
    <div >
      <button 
              data-item-id="11">
        <span >Like</span>
        <span>0</span>
      </button>
    </div>
    
    <div >
      <button 
              data-item-id="12">
        <span >Dislike</span>
        <span>1</span>
      </button>
    </div>
    
  </div>
</div><!-- comment -->

  • Related