2016-11-09 6 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()'が役立つかもしれませんが、この場合は別の方法が必要です。私はあなたが "反応モーダル"を検索するときにオンラインで多くの例があると確信しています。 –

関連する問題