Quero fechar um menu suspenso quando ocorre um clique fora do componente suspenso.
Como faço isso?
No elemento que eu adicionei mousedown
e mouseup
assim:
onMouseDown={this.props.onMouseDown} onMouseUp={this.props.onMouseUp}
Então no pai eu faço isso:
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;
}
O showCal
é um booleano que quando true
mostra no meu caso um calendário e o false
esconde.
preventDefault()
os eventos imediatamente ou o comportamento nativo do Android entra em ação, interferindo no pré-processamento do React. Escrevi npmjs.com/package/react-onclickoutside desde então.Usando os métodos de ciclo de vida, adicione e remova ouvintes de eventos do documento.
Verifique as linhas 48-54 deste componente: https://github.com/i-like-robots/react-tube-tracker/blob/91dc0129a1f6077bef57ea4ad9a860be0c600e9d/app/component/tube-tracker.jsx#L48-54
fonte
Observe o destino do evento, se o evento estava diretamente no componente, ou nos filhos desse componente, então o clique estava dentro. Caso contrário, estava fora.
Se for usado em muitos componentes, é melhor com um mixin:
Veja o exemplo aqui: https://jsfiddle.net/0Lshs7mg/1/
fonte
this.refs.component
está se referindo ao elemento DOM a partir de 0,14 facebook.github.io/react/blog/2015/07/03/…Para o seu caso de uso específico, a resposta atualmente aceita é um pouco exagerada. Se você deseja ouvir quando um usuário clica em uma lista suspensa, simplesmente use um
<select>
componente como o elemento pai e anexe umonBlur
manipulador a ele.A única desvantagem dessa abordagem é que ela assume que o usuário já manteve o foco no elemento e depende de um controle de formulário (que pode ou não ser o que você deseja se você levar em consideração que a
tab
chave também focaliza e desfoca os elementos ) - mas essas desvantagens são apenas um limite para casos de uso mais complicados, caso em que uma solução mais complicada pode ser necessária.fonte
onBlur
div também funciona com div se tivertabIndex
atributoEu escrevi um manipulador de eventos genérico para eventos que se originam fora do componente, react-outside-event .
A implementação em si é simples:
window
objeto.onOutsideEvent
no componente de destino.Para usar o componente, você precisa envolver a declaração da classe do componente de destino usando o componente de ordem superior e definir os eventos que deseja manipular:
fonte
Votei em uma das respostas, embora não tenha funcionado para mim. Isso acabou me levando a essa solução. Mudei ligeiramente a ordem das operações. Escuto mouseDown no alvo e mouseUp no alvo. Se algum deles retornar TRUE, não fechamos o modal. Assim que um clique é registrado, em qualquer lugar, esses dois booleanos {mouseDownOnModal, mouseUpOnModal} são redefinidos como falsos.
Isso tem a vantagem de que todo o código fica com o componente filho, e não com o pai. Isso significa que não há código padrão para copiar ao reutilizar esse componente.
fonte
.backdrop
)..target
) fora do.backdrop
elemento e com um índice de empilhamento maior (z-index
).Então, qualquer clique no
.backdrop
elemento será considerado "fora do.target
elemento".fonte
Você pode usar
ref
s para conseguir isso, algo como o seguinte deve funcionar.Adicione o
ref
ao seu elemento:Você pode então adicionar uma função para lidar com o clique fora do elemento, como:
Então, finalmente, adicione e remova os ouvintes de eventos em que serão montados e desmontados.
fonte
handleClickOutside
emdocument.addEventListener()
adicionandothis
referência. Caso contrário, fornece Uncaught ReferenceError: handleClickOutside não está definido emcomponentWillMount()
Muito tarde para a festa, mas tive sucesso com a configuração de um evento de desfoque no elemento pai da lista suspensa com o código associado para fechar a lista suspensa e também anexando um ouvinte mousedown ao elemento pai que verifica se a lista suspensa está aberta ou não, e interromperá a propagação do evento se estiver aberto para que o evento de desfoque não seja acionado.
Uma vez que o evento de movimento do mouse borbulha, isso impedirá que qualquer movimento do mouse nas crianças cause um desfoque nos pais.
e.preventDefault () não deveria ser chamado tanto quanto eu posso raciocinar, mas o firefox não joga bem sem ele por qualquer motivo. Funciona no Chrome, Firefox e Safari.
fonte
Eu encontrei uma maneira mais simples de fazer isso.
Você só precisa adicionar
onHide(this.closeFunction)
o modalSupondo que você tenha uma função para fechar o modal.
fonte
Use o excelente mixin reagir ao clicar fora :
E depois
fonte