Haga clic en Detector exterior

Es una experiencia de usuario razonable que puedas hacer clic para abrir algo, y luego no solo poder hacer clic en lo mismo para cerrarlo, sino también hacer clic fuera de lo que se abrió para cerrarlo. Kitty Giraudel acaba de escribir un blog sobre eso. El truco es que una vez que se abre el objeto, se adjunta un controlador de eventos window
que observa los eventos (como otro clic). Si ese clic posterior no se produce dentro del área recién abierta, ciérrela. Como, literalmente thing.contains(event.target)
. Es un buen truco, creo.
Sin embargo, hay muchas pequeñas cosas en las que pensar. Por ejemplo:
Tenemos que detener la propagación del evento de clic en el propio interruptor. De lo contrario, sube al detector de clics de la ventana y, dado que el interruptor no está contenido en el menú, cerrará este último tan pronto como intentemos abrirlo.
Bien bien. No puedo tener eso o lo arruinará todo.
Tenemos este mismo patrón en muchos lugares de CodePen. Al igual que Kitty, lo tenemos implementado en React. Al echar un vistazo a nuestra implementación, hay una serie de detalles que pensé que valía la pena mencionar. Por ejemplo, la nuestra no es una función o un gancho, sino un contenedor de componentes que usamos como:
ClickOutsideDetector listen onClickOutside={() = { closeTheThing(); }} A Menu or Modal or something./ClickOutsideDetector
De esa manera, es un contenedor genérico que podemos usar para cualquier cosa con un “clic externo”. Las campanas y silbatos son:
- Puedes pasar
component
prop para que no tengas que manifestarse como algo,div
sino lo que quieras que sea semánticamente. - El
listen
accesorio le permite alternar si actualmente está escuchando activamente eventos. Como una manera rápida de cortocircuitarlo. - Pulsar una tecla ESC es el equivalente funcional a hacer clic afuera.
- Maneja eventos táctiles y clics.
- Maneja un caso en el que el clic externo ocurre en un
iframe
caso en el quewindow
tiene unblur
evento en lugar de un clic. - Le permite pasar elementos para ignorar, por lo que, en lugar del
stopPropagation
truco que documentó Kitty, podemos ser específicos sobre los elementos que no activan un clic externo.
¡Tantas pequeñas cosas! Para mí, este es el pequeño ejemplo perfecto de desarrollo en el mundo real. Sólo quieres un pequeño comportamiento y, en última instancia, hay un montón de consideraciones y casos extremos con los que tienes que lidiar y en realidad nunca se hace. Acabo de tocar nuestro componente en los últimos meses debido a que una herramienta de terceros que usó cambió la forma en que hacían algo que afectaba los iframes en uso en la página. Al final, tuve que estar atento a un blur
evento que luego verificó classList
para document.activeElement
ver si eso era lo que se estaba comiendo el clic afuera.
De todos modos, arrojé una versión ligeramente simplificada de la nuestra aquí.
Y vi algo en la publicación de Kitty que no estábamos manejando, y está en la primera oración:
Necesitábamos una forma de cerrar el menú al hacer clic fuera de él o al salir de él.
El énfasis es mío. No te preocupes, ahora tengo un TODO en nuestro código para eso.
Deja un comentario