D
D
Drovosek012021-07-19 13:31:32
JavaScript
Drovosek01, 2021-07-19 13:31:32

Why does the contains function not work correctly?

Good day.

An Angular 11 project uses the following function to track whether a click was made inside or outside of a component:

the code
import { fromEvent, Observable } from 'rxjs';
import { map } from 'rxjs/operators';

/**
 * Наблюдатель за DOM деревом, который может подтвердить/опровергнуть
 * принадлежность клика к указанному DOM элементу
 * @param clickOwnerElement - элемент, относитльно которого нужно подтверждать принадлежность кликов в DOM дереве,
 * предполагается, что клик на его дочернем элменте тоже делает его владельцем клика
 */
export const isOwnClick = (clickOwnerElement: HTMLElement): Observable<boolean> =>
  fromEvent(document, 'click').pipe(
    map((event: Event) => {
      const targetElement = event.target as HTMLElement;

      /** поймать момент, когда элемент уже уничтожен через ngIf */
      if (!targetElement) {
        return true;
      }

      /** узать принадлежность кликнутого элемента как дочернего для искомого элемента  */
      if (clickOwnerElement === targetElement || clickOwnerElement.contains(targetElement)) {
        return true;
      }

      return false;
    })
  );


Well, in the component code itself, we subscribe to events as follows:
the code
isOwnClick(this.hostElement.nativeElement)
      .pipe(filter((isInDropdownClick) => !isInDropdownClick))
      .subscribe(() => {
        this.calendarWindowState = CalendarWindowState.hide;
      });


The problem is that for some reason contains returns false even though targetElement is a child of clickOwnerElement . Not a direct child, but a child.

For example, here in the screenshot, the dropdown-calendar tag is just the same clickOwnerElement, and the highlighted tag is the targetElement that was clicked on.
0d68866c5a969f3d93378208f1a2846d.png

If I track focus instead of clicks (just change 'click' to 'focusin' in fromEvent , then everything works fine and I select the desired number in the calendar with Tab and press Enter, then contains returns true.

Actually, why contains returns true when clicked false even though the element being checked is a child?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question