Skip to content

Instantly share code, notes, and snippets.

@tspringborg
Last active December 18, 2019 14:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tspringborg/01b8b47a4f86b954dcb2e86e5501e5de to your computer and use it in GitHub Desktop.
Save tspringborg/01b8b47a4f86b954dcb2e86e5501e5de to your computer and use it in GitHub Desktop.
angular clickOutside directive
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