Estoy creando un menú de configuración para mi sitio que aparecería como una ventana emergente. Actualmente, puedo abrir/cerrar esta ventana emergente haciendo clic en el botón vinculado a ella. Sin embargo, me gustaría implementar una forma de cerrar esta ventana emergente/div simplemente haciendo clic fuera de la ventana emergente.
Creo que JavaScript puede completar esta acción, desafortunadamente, todavía no estoy bien versado en el uso de este lenguaje.
¿Alguien tiene una solución que satisfaga mis necesidades? Esto es con lo que estoy trabajando...
Gracias por adelantado :)
var settingsmenu = document.querySelector(".settings-menu"); function settingsMenuToggle(){ settingsmenu.classList.toggle("settings-menu-height"); } .settings-menu{ position: absolute; width: 90%; max-width: 350px; background: var(--color-light); box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); border-radius: 4px; overflow: hidden; top: 84px; right: 9%; max-height: 0; transition: max-height 0.3s; } .settings-menu-height{ max-height: 300px; } .settings-menu-inner{ padding: 20px; } <div class="create"> <figure onclick="settingsMenuToggle()"> <button>Open Popup</button> </figure> </div> <div class="settings-menu"> <div class="settings-menu-inner"> <figure> <img src="https://images.macrumors.com/t/Y_7ongT7QQ-k0uYwUE4uCoCO3TI=/800x0/article-new/2019/08/apple-settings-icon-19.jpg-250x250.jpg?lossy" width="100" height="100"> <h3>This is a popup</h3> </figure> </div> </div>Puede envolver su ventana emergente en otro elemento; es uno de los enfoques más fáciles. Digamos que tendrá la clase "tint" y dentro contendrá su div emergente. Y para capturar el evento en segundo plano, puede agregar un detector de eventos al documento y verificar el destino del clic cada vez. Si el destino del clic es el fondo (es decir, nuestro "tinte"), simplemente ocultamos el elemento "tint" y el evento no volverá a activarse porque una vez: verdadero. De lo contrario volvemos a configurar el evento. Por supuesto, es solo un fragmento simple para demostración. Puedes ampliarlo y modificarlo según tus necesidades.
function documentLoaded(fn) { if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading"){ fn(); } else { document.addEventListener('DOMContentLoaded', fn); } } function popupClickListener(e){ if (e.target.classList.contains('tint')) { document.querySelector('.tint').style.display = 'none'; } else { document.addEventListener('click', popupClickListener, {once: true}); } } documentLoaded(function(){ document.querySelector('.show-popup').onclick = function(){ document.querySelector('.tint').style.display = 'block'; document.addEventListener('click', popupClickListener, {once: true}); } }); .tint { position: fixed; display: none; width: 100%; height: 100vh; overflow-y: auto; overflow-x: hidden; background: rgba(0, 0, 0, 0.7); z-index: 10000; left: 0; right: 0; top: 0; bottom: 0; text-align: center; vertical-align: middle; } .popup { position: relative; display: inline-block; background: #fff; width: calc(100% - 20px); max-width: 550px; min-height: 130px; margin: 50px 10px; border-radius: 10px; vertical-align: middle; overflow: hidden; -webkit-transform: translateZ(0px); } <div class="tint"> <div class="popup">popup-content</div> </div> <div class="page-content"> some content<br> <button class="show-popup">show popup</button> </div>Es bastante fácil, envuelves tu popover actual en un div adicional; así que si actualmente tuvieras:
<div class="settings-menu"> ...stuff... </div>entonces lo conviertes en:
<div class="popover-backplate"> <div class="settings-menu"> ...stuff... </div> </div>A continuación, agrega algo de CSS como:
.popover-backplate { position: fixed; width: 100vw; height: 100vh; background-color: red; opacity: 0.5; } Si eso funcionó, debería haber una superposición roja semitransparente sobre toda la página (de todos modos, todo lo que esté fuera de la ventana emergente). Si ese no es el caso, es posible que deba agregar una propiedad z-index tanto a settings-menu como popover-backplate .
Una vez que la parte visual funciona, todo lo que queda es agregar un poco de javascript en popover-backplate s onclick -event, que llama a su popover_close() (como se llame).