How to detect click outside of an element in Angular?

前端 未结 7 773
死守一世寂寞
死守一世寂寞 2020-12-29 10:06

This div will be dynamically shown on the page as an east panel when the open panel button is clicked. The bool showEastPanel variable

相关标签:
7条回答
  • 2020-12-29 10:59

    Here's a reusable directive, it also cover the case if the element is inside an ngIf:

    import { Directive, ElementRef, Optional, Inject, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core';
    import { fromEvent, Subscription } from 'rxjs';
    import { DOCUMENT } from '@angular/common';
    import { filter } from 'rxjs/operators';
    
    @Directive({
      selector: '[outsideClick]',
    })
    export class OutsideClickDirective implements OnInit, OnDestroy {
      @Output('outsideClick') outsideClick = new EventEmitter<MouseEvent>();
    
      private subscription: Subscription;
    
      constructor(private element: ElementRef, @Optional() @Inject(DOCUMENT) private document: any) {}
    
      ngOnInit() {
        setTimeout(() => {
          this.subscription = fromEvent<MouseEvent>(this.document, 'click')
            .pipe(
              filter(event => {
                const clickTarget = event.target as HTMLElement;
                return !this.isOrContainsClickTarget(this.element.nativeElement, clickTarget);
              }),
            )
            .subscribe(event => this.outsideClick.emit());
        }, 0);
      }
    
      private isOrContainsClickTarget(element: HTMLElement, clickTarget: HTMLElement) {
        return element == clickTarget || element.contains(clickTarget);
      }
    
      ngOnDestroy() {
        if (this.subscription) this.subscription.unsubscribe();
      }
    }
    
    

    Credits to https://github.com/ngez/platform, I got most of the logic out of it.

    What I was missing was the setTimeout(..., 0), which makes sure to schedule the check after the component using the directive has been rendered.

    Useful links:

    • https://stackoverflow.com/a/779785/5869296
    • https://github.com/ngez/platform
    0 讨论(0)
提交回复
热议问题