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 } ); }
4 Réponses :
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'));
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); }
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> ); }
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 = () => {};
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!