Last active
December 18, 2019 14:49
-
-
Save tspringborg/01b8b47a4f86b954dcb2e86e5501e5de to your computer and use it in GitHub Desktop.
angular clickOutside directive
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Directive, ElementRef, EventEmitter, HostListener, Output} from '@angular/core'; | |
@Directive({ | |
// tslint:disable-next-line:directive-selector | |
selector: '[clickOutside]' | |
}) | |
export class ClickOutsideDirective { | |
private readonly startTime: number; | |
constructor(private elementRef: ElementRef) { | |
this.startTime = new Date().getTime(); | |
} | |
@Output('clickOutside') clickOutside: EventEmitter<any> = new EventEmitter(); | |
@HostListener('document:click', ['$event']) onMouseEnter(evt) { | |
if (new Date().getTime() - this.startTime > 80) { | |
// make sure it doesn't fire immediately. | |
// like when clicking another element to show component with this directive. | |
const targetElement = evt.target; | |
const insideRect: ClientRect = this.elementRef.nativeElement.getBoundingClientRect(); | |
const cX = evt.clientX; | |
const cY = evt.clientY; | |
const clickedInsideRect = ( | |
cX >= insideRect.left && cX <= insideRect.left + insideRect.width | |
&& cY >= insideRect.top && cY <= insideRect.top + insideRect.height | |
); | |
// doesn't always work since element might be removed from dom when clicked | |
// const clickedInside = this.elementRef.nativeElement.contains(targetElement); | |
if (!clickedInsideRect) { | |
this.clickOutside.emit(null); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment