Je souhaite fermer un menu déroulant lorsqu'un clic se produit en dehors du composant déroulant.
Comment je fais ça?
Dans l'élément que j'ai ajouté mousedown
et mouseup
comme ceci:
onMouseDown={this.props.onMouseDown} onMouseUp={this.props.onMouseUp}
Ensuite, chez le parent, je fais ceci:
componentDidMount: function () {
window.addEventListener('mousedown', this.pageClick, false);
},
pageClick: function (e) {
if (this.mouseIsDownOnCalendar) {
return;
}
this.setState({
showCal: false
});
},
mouseDownHandler: function () {
this.mouseIsDownOnCalendar = true;
},
mouseUpHandler: function () {
this.mouseIsDownOnCalendar = false;
}
Le showCal
est un booléen qui true
montre dans mon cas un calendrier et le false
cache.
preventDefault()
les événements immédiatement ou le comportement natif d'Android entre en action, ce qui interfère avec le prétraitement de React. J'ai écrit npmjs.com/package/react-onclickoutside depuis.À l'aide des méthodes de cycle de vie, ajoutez et supprimez des écouteurs d'événements dans le document.
Consultez les lignes 48-54 de ce composant: https://github.com/i-like-robots/react-tube-tracker/blob/91dc0129a1f6077bef57ea4ad9a860be0c600e9d/app/component/tube-tracker.jsx#L48-54
la source
Regardez la cible de l'événement, si l'événement était directement sur le composant, ou les enfants de ce composant, alors le clic était à l'intérieur. Sinon, c'était à l'extérieur.
Si cela doit être utilisé dans de nombreux composants, c'est mieux avec un mixin:
Voir l'exemple ici: https://jsfiddle.net/0Lshs7mg/1/
la source
this.refs.component
fait référence à l'élément DOM à partir de 0,14 facebook.github.io/react/blog/2015/07/03/…Pour votre cas d'utilisation spécifique, la réponse actuellement acceptée est un peu sur-conçue. Si vous voulez écouter quand un utilisateur clique hors d'une liste déroulante, utilisez simplement un
<select>
composant comme élément parent et attachez unonBlur
gestionnaire.Le seul inconvénient de cette approche est qu'elle suppose que l'utilisateur a déjà maintenu le focus sur l'élément, et qu'elle repose sur un contrôle de formulaire (qui peut ou non être ce que vous voulez si vous prenez en compte que la
tab
clé se concentre également et brouille les éléments ) - mais ces inconvénients ne sont vraiment qu'une limite pour des cas d'utilisation plus compliqués, auquel cas une solution plus compliquée pourrait être nécessaire.la source
onBlur
div fonctionne également avec div s'il a untabIndex
attributJ'ai écrit un gestionnaire d'événements générique pour les événements qui proviennent de l'extérieur du composant, react-outside-event .
La mise en œuvre elle-même est simple:
window
objet.onOutsideEvent
sur le composant cible.Pour utiliser le composant, vous devez encapsuler la déclaration de classe de composant cible à l'aide du composant d'ordre supérieur et définir les événements que vous souhaitez gérer:
la source
J'ai voté pour l'une des réponses même si cela n'a pas fonctionné pour moi. Cela a fini par m'amener à cette solution. J'ai légèrement changé l'ordre des opérations. J'écoute mouseDown sur la cible et mouseUp sur la cible. Si l'un de ceux-ci retourne TRUE, nous ne fermons pas le modal. Dès qu'un clic est enregistré, n'importe où, ces deux booléens {mouseDownOnModal, mouseUpOnModal} sont remis à false.
Cela présente l'avantage que tout le code repose sur le composant enfant et non sur le parent. Cela signifie qu'il n'y a pas de code standard à copier lors de la réutilisation de ce composant.
la source
.backdrop
)..target
) en dehors de l'.backdrop
élément et avec un index d'empilement supérieur (z-index
).Ensuite, tout clic sur l'
.backdrop
élément sera considéré "en dehors de l'.target
élément".la source
Vous pourriez utiliser
ref
s pour y parvenir, quelque chose comme ce qui suit devrait fonctionner.Ajoutez le
ref
à votre élément:Vous pouvez ensuite ajouter une fonction pour gérer le clic en dehors de l'élément comme ceci:
Puis enfin, ajoutez et supprimez les écouteurs d'événement sur le montage et le démontage.
la source
handleClickOutside
endocument.addEventListener()
ajoutant unethis
référence. Sinon, cela donne Uncaught ReferenceError: handleClickOutside n'est pas défini danscomponentWillMount()
Super tard à la fête, mais j'ai réussi à définir un événement de flou sur l'élément parent de la liste déroulante avec le code associé pour fermer la liste déroulante, et également à attacher un écouteur mousedown à l'élément parent qui vérifie si la liste déroulante est ouverte ou non, et arrêtera la propagation de l'événement s'il est ouvert afin que l'événement de flou ne soit pas déclenché.
Puisque l'événement mousedown bouillonne, cela empêchera tout mousedown sur les enfants de provoquer un flou sur le parent.
e.preventDefault () ne devrait pas avoir à être appelé pour autant que je sache, mais Firefox ne joue pas bien sans lui pour une raison quelconque. Fonctionne sur Chrome, Firefox et Safari.
la source
J'ai trouvé un moyen plus simple à ce sujet.
Il vous suffit d'ajouter
onHide(this.closeFunction)
le modalEn supposant que vous ayez une fonction pour fermer le modal.
la source
Utilisez l'excellent mixin réact-onclickoutside :
Puis
la source