Как проверить, была ли цель события внутри того или иного элемента? - PullRequest
0 голосов
/ 08 мая 2018

У меня есть компонент «Карта», который прослушивает внешнее событие щелчка или прокрутки и уничтожается при возникновении этого события.

@HostListener('document:mousedown', ['$event'])
public onEvent(e: Event): void {
    let el = this.elementRef.nativeElement;
    if (e.target !== el && !el.contains(e.target)) {
        this.destroyCard();
    }
}

ngAfterViewInit() {
  document.addEventListener('scroll', this.onEvent, true);
}

Проблема возникает, когда из этого компонента я создаю модальное окно, которое создается снаружиэтот компонент в корне представления приложения.Когда я нажимаю на модальное окно или прокручиваю его, компонент моей карты уничтожается вместе с модальным окном.

Вот песочница stackblitz с щелчком .При нажатии на модальное окно оно должно остаться.

ОБНОВЛЕНО .Исправлено с помощью event.stopPropagation ().

Но это не работает для таких событий, которые обычно не пузырьковые, как прокрутка.Пожалуйста, посмотрите stackblitz с прокруткой .

Я вижу только одно решение: создать сервис, который будет прослушивать события, и мой компонент Card и компонент модального окна будут подписываться и добавлять их узлы в массив, который будетпроверил, находится ли цель события внутри этих узлов или нет.

Может, кто-нибудь знает лучшее решение?

1 Ответ

0 голосов
/ 10 мая 2018

Вы можете обработать событие mousedown в модальном компоненте и вызвать event.stopPropagation(), чтобы убедиться, что оно не достигает уровня document.Вы можете увидеть результат в этот стек .

export class ModalWindowComponent {
    @HostListener('mousedown', ['$event'])
    public processMouseDown(event: MouseEvent): void {
        event.stopPropagation();
    }
}

Важно : Обязательно вызовите event.stopPropagation(), а не event.stopImmediatePropagation().

  • event.stopPropagation() предотвращает пузыри события для предков элемента (см. Документация MDN )
  • event.stopImmediatePropagation() просто запрещает оставшимся слушателямэлемент от вызова (см. документация MDN )

Для события прокрутки вызов event.stopPropagation не работает.Вы можете оставить модальный режим открытым, если у элемента прокрутки есть определенный атрибут, например data-keepmodalopen="true" (в нижнем регистре).Вот код для этого вида проверки (см. этот стековый блик для демонстрации):

<div class="container">Modal window. I should stay
  <div class="scroll-container" data-keepmodalopen="true">
    ...
  </div>
</div>
public onScroll(e: MouseEvent): void {
  if (this.window && !this.keepModelOpen(e.target as HTMLElement)) {
    this.window.destroy();
    this.window = null;
  }
}

public keepModelOpen(element: HTMLElement): boolean {
  return element.dataset.keepmodalopen === "true";
}
...