4
votes

Réagir Javascript en cliquant en dehors de div

 logout with svg icon

Je travaille sur un site Web et actuellement j'ai une icône svg pour me déconnecter. lorsque l'icône est cliquée, une superposition s'affiche avec l'option de déconnexion. lorsque l'utilisateur clique sur la déconnexion, il doit effectuer certaines opérations et lorsque l'utilisateur clique en dehors de la superposition div doit être masquée. Je ne parviens pas à atteindre cet objectif.

J'ai essayé de donner le focus à div en utilisant tabIndex mais l'option de déconnexion n'est plus cliquable.

Header.js

 import React, { Component } from "react";
    import ReactDOM from "react-dom";
    class MainHeader extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          logOutShown: false
        };
      }
    render() {
    var guiResult = [];
    if (this.state.logOutShown) {
      guiResult.push(
        <div className="Login__Overlay__Frame">
          <div className="User__Login__Overlay">
          <div className="Login__Content" tabIndex="1" onFocus={this.alerting.bind(this)} onBlur={this.toggleOverlay.bind(this)}>Signout</div>
          </div>
        </div>
      );
    }

    return (
            <div className="Header__Icon">
              <div className="Icons__Log__In" tabIndex="0" onClick={this.validate.bind(this)} onBlur={this.toggleOverlay.bind(this)}/>
              {guiResult}
            </div>
    );
  }

  toggleOverlay(){
    console.log("toggle overlay");
    this.setState({ logOutShown: false});
  }

  validate() {
    console.log("validate:");
    this.setState(
      {
        logOutShown: true
      }
    );
  }


7 commentaires

Vous pouvez ajouter des gestionnaires à la superposition


Vous pouvez vérifier le clic sur la superposition, mais il y a un problème !!. Lorsque vous cliquez sur quelque chose à l'intérieur de la superposition, il le capte également. Ce que j'ai tendance à faire est de créer un composant pour faire la superposition, et à l'intérieur de la superposition, il y a un conteneur, et ce conteneur s'attache à onClick et appelle event.stopPropagation () . Cela arrêtera alors les clics sur votre contenu déclenchant l'événement sur la superposition.


@Keith je vais essayer maintenant en créant un nouveau composant pour la superposition. peut-être pouvez-vous me fournir la structure globale du nouveau composant qui ressemblera à ce que je me suis trompé dans ce "et à l'intérieur de la superposition, il y a un conteneur, et ce conteneur s'attache à onClick et appelle event.stopPropagation ()"


@Kirill comme Keith l'a mentionné, cela n'a pas fonctionné.


Je vais voir si je peux faire un petit extrait. donnez-nous 10 ..


@Keith merci


Les roches de la solution @Keith! meilleur de loin. merci @Keith!


4 Réponses :


5
votes

Voici un exemple simple, j'utilise des hooks React ici au lieu de classes, mais vous pouvez aussi utiliser des classes.

La partie principale est le onClick sur le conteneur div, si vous exécutez l'exemple ci-dessous et cliquez sur la boîte de dialogue, il ne la fermera pas, mais cliquer sur la superposition le fera.

Le e.stopPropagation () sur le conteneur div est ce qui arrête le déclenchement des événements sur le contenu les événements sur la superposition. Au lieu d'utiliser stopPropagation , une autre option consiste à vérifier la target & currentTarget à l'intérieur de la superposition onClick ..

p >

<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="mount"></div>
.overlay {
  position: fixed;
  background-color: rgba(100,100,100,0.5);
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
}

.overlay-container {
  border: 1px solid black;
  background-color: white;
  position: absolute;
  top: 30px;
  left: 30px;
  width: 200px;
  height: 80px;
  padding: 5px;
}
const {useState} = React;


function Overlay(props) {
  const {contents} = props;
  const [open, setOpen] = useState(true);
  if (open) {
    return <div className="overlay" onClick={() => setOpen(false)}>
      <div onClick={(e) => {
        //stop clicks getting to the overlay
        e.stopPropagation();
      }}className="overlay-container">
        {contents()}
      </div>
    </div>
  }
  return null;
}


ReactDOM.render(<React.Fragment>
  This is some content to overlay.<br/>
  for testing..
  <Overlay contents={() =>
    <div>This is the contents, clicking here wont effect ovelay</div>
  }/>
</React.Fragment>, document.querySelector('#mount'));


0 commentaires

3
votes

Utilisez les références de réaction https://reactjs.org/ docs / refs-and-the-dom.html # creation-refs

Vous vérifiez la cible de l'événement et l'utilisez pour afficher / masquer code > le bouton de déconnexion.

ajouter un écouteur d'événement lorsque le composant est monté.

handleClickOutside(e) {
    if(this.submitPopoverRef.contains(e.target)) {
        // the click happened in the component
        // code to handle the submit button
        // submit();
        return;
    } 

    // click happened outside the component
    // hide the popover
    this.handleClick(); // set the state false
}

<div ref={node => this.submitPopoverRef = node}> 
... Your code here...

</div>

supprimer l'écouteur d'événement lorsque le composant est monté.

componentWillUnmount() { document.removeEventListener("click", this.handleClickOutside, false); }

faire la vérification pour le clic extérieur quelque chose comme ça p>

componentWillMount() { document.addEventListener("click", this.handleClickOutside, false); }


0 commentaires

5
votes

Vous pouvez utiliser une bibliothèque bien écrite comme celle-ci: react-outside-click-handler

example:

import OutsideClickHandler from 'react-outside-click-handler';

function MyComponent() {
  return (
    <OutsideClickHandler
      onOutsideClick={() => {
        alert('You clicked outside of this component!!!');
      }}
    >
      Hello World
    </OutsideClickHandler>
  );
}


0 commentaires

0
votes

D'après la réponse de @ keith: Utilisation des hooks React ainsi que des classes: En supposant un div parent et un div enfant, où vous souhaitez que le div parent gère le clic UNIQUEMENT lorsque le clic ne se trouvait pas dans le div enfant:

<div onClick={clickedParent}>
  <div className="selc-hd-so-remove" onClick={e=> { e.stopPropagation(); clickedChild(); }} > Child Div Clicked</div>
</div>
Parent Div Clicked
</div>

const clickedParent = () => {};
const clickedChild = () => {};


0 commentaires