2016-11-09 12 views
7

Mam element o nazwie Dialog, w którym dołączam detektor zdarzeń po kliknięciu myszą na obiekcie window.Jak sprawdzić, czy użytkownik kliknął wewnątrz bieżącego komponentu?

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

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

jaki sposób można wykryć (w funkcji handleClick) czy kliknięcie został zwolniony wewnątrz komponentu lub zewnętrznym? Zauważ, że to okno dialogowe zawiera różne elementy i komponenty potomne.

+0

mogę znaleźć na to pytanie o wykryciu kliknięcia na zewnątrz elementu. http://stackoverflow.com/questions/32553158/detect-click-outside-react-component Myślę, że możesz obejść i wykryć kliknięcia wewnątrz komponentu. – Jackowski

+0

@Jackowski dzięki, spróbuję tego. Przyjęta odpowiedź (sam autor) stwierdza, że ​​miał problem z dołączeniem wywołania zwrotnego do treści dokumentu: "Ponieważ wywołanie React następuje przed wywołaniem procedury obsługi treści dokumentu, element nie został wykryty jako" wewnątrz "drzewa." Każdy pomysł, dlaczego? – Matthew

Odpowiedz

10

parent.contains(child) jest twoim przyjacielem. To rozwiązanie z użyciem refs może nie być idealne, ale po prostu użycie this nie działa, ponieważ nie jest prawidłowym węzłem DOM. Używam React 15 tutaj, więc należy pamiętać, że we wcześniejszych wersjach musiałbyś użyć .getDOMNode() na rodzica.

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

Dzięki! Być może zgadłeś, że próbuję uczynić dialog modalnym dialogiem. Jednak implementując kod zdałem sobie sprawę, że całkowicie skręciłem: jeśli kliknę element poza oknem dialogowym, to najpierw zostanie uruchomiona obsługa zdarzenia tego elementu, powodując ponowne renderowanie i utracę okno dialogowe ... Miałem nadzieję, że callback "handleClick" będzie miał przede wszystkim priorytet, tak, żebym mógł zatrzymać dalsze przetwarzanie zdarzenia, jeśli kliknęłby poza tym oknem dialogowym ... Myślę, że mój pomysł nie zadziała właściwie ... Jakakolwiek rada? – Matthew

+1

Może 'e.preventDefault()' pomaga, ale myślę, że w tym przypadku potrzebujesz innego podejścia. Jestem pewien, że istnieje wiele przykładów w Internecie, gdy szukasz "modów reagowania". –

Powiązane problemy