Я бы сделал это, используя рекомендованный Angular подход, который также прост в разработке приложений в средах без доступа DOM, я имею в виду класс Renderer 2
, который является абстракцией, предоставляемой Angular в форме сервис, который позволяет манипулировать элементами вашего приложения без непосредственного прикосновения к DOM.
В этом подходе вам нужно вставить Renderer2
в конструктор вашего компонента, который Renderer2
позволяет нам listen
элегантно запускать события. Он просто принимает элемент, который вы собираетесь прослушивать, в качестве первого аргумента, который может быть window
, document
, body
или любой другой ссылкой на элемент. Для второго аргумента требуется событие, которое мы собираемся прослушать, в данном случае это click
, а третий аргумент на самом деле является функцией обратного вызова, которую мы делаем с помощью функции стрелки.
this.renderer.listen('window', 'click',(e:Event)=>{ // your code here})
Остальное решение простое, вам просто нужно установить логический флаг, который сохраняет статус видимости меню (или панели), и нам нужно назначить false
этому флагу, когда он щелкает снаружи меню.
Вот ссылка на Stackblitz Demo
HTML
<button #toggleButton (click)="toggleMenu()"> Toggle Menu</button>
<div class="menu" *ngIf="isMenuOpen" #menu>
I'm the menu. Click outside to close me
</div>
app.component.ts
export class AppComponent {
/**
* This is the toogle button elemenbt, look at HTML and see its defination
*/
@ViewChild('toggleButton') toggleButton: ElementRef;
@ViewChild('menu') menu: ElementRef;
constructor(private renderer: Renderer2) {
/**
* This events get called by all clicks on the page
*/
this.renderer.listen('window', 'click',(e:Event)=>{
/**
* Only run when toggleButton is not clicked
* If we don't check this, all clicks (even on the toggle button) gets into this
* section which in the result we might never see the menu open!
* And the menu itself is checked here, and it's where we check just outside of
* the menu and button the condition abbove must close the menu
*/
if(e.target !== this.toggleButton.nativeElement && e.target!==this.menu.nativeElement){
this.isMenuOpen=false;
}
});
}
isMenuOpen = false;
toggleMenu() {
this.isMenuOpen = !this.isMenuOpen;
}
}