Last active
January 19, 2016 14:59
-
-
Save DouglasLivingstone/1c42108412bb12267a1c to your computer and use it in GitHub Desktop.
TypeScript OnClickOutsideHandler
This file contains hidden or 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
// 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