Skip to content

Instantly share code, notes, and snippets.

@DouglasLivingstone
Last active January 19, 2016 14:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DouglasLivingstone/1c42108412bb12267a1c to your computer and use it in GitHub Desktop.
Save DouglasLivingstone/1c42108412bb12267a1c to your computer and use it in GitHub Desktop.
TypeScript OnClickOutsideHandler
// Refactored from https://github.com/Pomax/react-onclickoutside
class OnClickOutsideHandler {
constructor(private localNode: Element, private callback: { (event: Event): void }) {
if (!callback) throw new Error("Missing callback");
document.addEventListener("mousedown", this.eventHandler);
document.addEventListener("touchstart", this.eventHandler);
}
private eventHandler = (event: Event) => {
var source: Node = <any>event.target;
var found = false;
// If source=local then this event came from "somewhere"
// inside and should be ignored. We could handle this with
// a layered approach, too, but that requires going back to
// thinking in terms of Dom node nesting, running counter
// to React's "you shouldn't care about the DOM" philosophy.
while (source.parentNode) {
found = (source === this.localNode);
if (found) return;
source = source.parentNode;
}
this.callback(event);
}
dispose() {
document.removeEventListener("mousedown", this.eventHandler);
document.removeEventListener("touchstart", this.eventHandler);
}
}
/* Usage inside a React component: */
class Dropdown {
render() {
// render...
}
private clickOutsideHandler: OnClickOutsideHandler;
componentDidMount() {
this.clickOutsideHandler = new OnClickOutsideHandler(this.getDOMNode(), () => {
// handle click...
});
}
componentWillUnmount() {
this.clickOutsideHandler.dispose();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment