Ben Racicot
Ben Racicot

Reputation: 5951

Advanced Angular @HostListener - Logging clicks for all elements within parent component (from child)

I want to keep the logic for a child component inside of it. However the event itself is when a click occurs from its parent component down.

child.component.ts

@HostListener('document:click', ['$event']) onClick(event: MouseEvent) {

  // get the parent component tag
  const parentComponent = this.eRef.nativeElement.parentNode.parentNode;

  for (let i = 0, j = parentComponent.length; i < j; i++) {
    if (event.target == parentComponent[i]) {
        console.log(parentComponent[i]);
    }
  }

I've tried many things to iterate through the node list and compare the click event.target to see if the click was inside parent or outside but I can't seem to iterate the nodeList and don't understand why.

I've tried many other things as well here at the repro StackBlitz.

Perhaps there is a much better way to watch for clicks outside/inside this component's parent? Also, I don't want to move the click logic to the parent, the logic doesn't belong there unless it has to be.

FIXED: The StackBlitz has been updated with all my research on traversing the DOM with elementRef. Also @Ritchie looped through the nodeList properly and got it to work that way.

Upvotes: 1

Views: 1697

Answers (1)

Ritchie
Ritchie

Reputation: 562

You can use the target property of the MouseEvent to check which component was clicked and compare it with the parents node name.

@HostListener('document:click', ['$event.target']) onClick(event) {
    const parentEl = this.eRef.nativeElement.parentNode.tagName;

    const path = [];
    let currentElem = event;
    while (currentElem) {
      path.push(currentElem.tagName);
      currentElem = currentElem.parentElement;
    }
    console.log('Clicked inside parent: ', path.includes(parentEl));
}

Stackblitz Example

Upvotes: 2

Related Questions