2016-11-09 82 views
7

我有一个名为Dialog的组件,其中我在window对象上的鼠标单击上附加了一个事件侦听器。如何检查用户是否在当前组件内单击?

componentDidMount() { 
    document.addEventListener('click', this.handleClick); 
} 

componentWillUnmount() { 
    document.removeEventListener('click', this.handleClick); 
} 

我怎样才能检测(在​​功能)是否有点击的组件内部还是外部的被解雇?请注意,此对话框包含不同的元素和子组件。

+0

我发现关于组件的外部检测的点击这个问题。 http://stackoverflow.com/questions/32553158/detect-click-outside-react-component我想你可以解决方案,并检测组件内的点击。 – Jackowski

+0

@Jackowski谢谢,我会尝试。被接受的答案(作者自己)声明他将点击回调附加到文档主体时存在问题:“因为React的重新渲染发生在文档主体处理程序被调用之前,所以元素没有被检测为”在树内“。任何想法为什么? – Matthew

回答

10

parent.contains(child)是你的朋友。使用refs的此解决方案可能并不完美,但仅使用this不起作用,因为它不是合适的DOM节点。我在这里使用React 15,所以请记住,在早期版本中,您必须在父项上使用.getDOMNode()

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>

+0

谢谢!也许你猜到我试图让对话成为模态对话框。然而,通过实现代码,我意识到我完全搞砸了:如果我点击对话框外的元素,那么首先会执行该元素上的事件处理程序,导致重新呈现,并且我将失去对话...我希望是“handleClick”回调优先,所以我可以阻止事件进一步处理,如果在对话框外单击...我认为我的想法实际上不会工作...任何建议? – Matthew

+1

也许'e.preventDefault()'有帮助,但我认为在这种情况下,您需要一种不同的方法。当你搜索“反应模式”时,我确信在线有很多例子。 –

相关问题