Доброго времени суток.
На Angular 11 проекте используется следующая функция для отслеживания того, был ли сделан клик внутри компонента или снаружи:
код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;
})
);
Ну и в самом коде компонента подписываемся на события следующим образом:
кодisOwnClick(this.hostElement.nativeElement)
.pipe(filter((isInDropdownClick) => !isInDropdownClick))
.subscribe(() => {
this.calendarWindowState = CalendarWindowState.hide;
});
Проблема в том, что по какой-то причине contains возвращает false, хотя targetElement является дочерним элементом по отношению к clickOwnerElement. Не прямым ребенком, но дочерним.
Например здесь на скриншоте тег dropdown-calendar является как раз таки clickOwnerElement, а выделенный тег является targetElement'ом, по которому кликнули мышкой.
Если я вместо кликов буду отслеживать фокус (просто в fromEvent поменяю 'click' на 'focusin', то все работает нормальной и кода я в календаре Tab'ом выделяю нужное число и нажимаю Enter, то contains возвращает true.
Собственно почему contains при клике возвращает false, хотя проверяемый элемент является дочерним?