Reputation: 11260
I have a component called Dialog
, in which I attach an event listener on mouse clicks on the window
object.
componentDidMount() {
document.addEventListener('click', this.handleClick);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClick);
}
How can I detect (in the handleClick
function) whether a click has been fired inside the component or outside? Note that this dialog contains different elements and child components.
Upvotes: 18
Views: 19841
Reputation: 18546
parent.contains(child)
is your friend. This solution using refs
might not be perfect, but simply using this
does not work as it's not a proper DOM node. I'm using React 15 here, so keep in mind that in earlier versions you'd have to use .getDOMNode()
on the parent.
class Dialog extends React.Component {
constructor() {
super();
this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
document.addEventListener('click', this.handleClick);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClick);
}
handleClick(e) {
if (this.node.contains(e.target)) {
console.log('You clicked INSIDE the component.')
} else {
console.log('You clicked OUTSIDE the component.')
}
}
render() {
return(
<span ref={node => this.node = node}>
Level 0<br/>
<span>
Level 1.<br/>
<span>Level 2.</span>
</span>
</span>
);
}
}
ReactDOM.render(<Dialog/>, document.getElementById('View'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="View"></div>
Upvotes: 27