1

I have multiple elements in DOM with the same class name - 'ps__rail-y'. I want to iterateover those elements and listen to click event on individual element with the class and stop event propagation. I have tried the approach below, but somehow it is not working.

onClickScrollBar(){
    let elements : Array<any> = this._elRef.nativeElement.querySelectorAll('.ps__rail-y');
    elements.forEach((index : number) => {
      let element = document.getElementsByClassName('ps__rail-y')[index] as HTMLElement;
      element.addEventListener('click', (e : Event) => {
        e.stopPropagation()
      }, true)
    })
  }
RAHUL KUNDU
  • 745
  • 2
  • 12
  • 33

1 Answers1

3

First document.getElementsByClassName('ps__rail-y')\[index\] is really bad code.

Really, the best thing to do is to utilize "event delegation", where you only set up one event handler at an ancestor of all the elements that "might" trigger the event and let the event bubble up to that ancestor. Then, when it is handled at the ancestor, you can reference the event.target, which will reference the actual element that initiated the event. This way, you only set up one handler instead of many and you do it without any looping.

Here's an example:

// Set up the handler at an ancestor
document.querySelector("section").addEventListener("click", function(event){
  // Only act if the actual element that triggered the event
  // has a certain class
  if(event.target.classList.contains("foo")){
    console.log("You clicked the " + event.target.nodeName + " element.");
  }
});
<section>
  <div class="foo">Click me</div>
  <h1 class="foo">Click me</h1>
  <div>Click me  <span>Click me</span></div>
  <p>Click me</p>  
  <a href="#" class="foo">Click me</a>  
</section>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • thank you for the reply, I have tried this way and it is working what do you think about this approach - `let elements : Array = this._elRef.nativeElement.querySelectorAll('.ps__rail-y'); elements.forEach((element : HTMLElement) => { element.addEventListener('click', (e : Event) => { e.stopPropagation() }, true) })` – RAHUL KUNDU Jan 09 '21 at 17:34
  • I am not a fan of looping to find multiple elements and having to have each store an identical handler. It's just a waste of time and memory. The preferred approach is my answer where you find one element and assign one handler. – Scott Marcus Jan 09 '21 at 17:41