Tengo una superposición simple en la que quiero capturar eventos de clic. El problema es que no quiero que ningún clic que ocurra dentro del contenido de la superposición desencadene un evento. Por ejemplo, si observa mi fragmento de código a continuación, hacer clic dentro del div .content no debería activar el detector de eventos de clic que configuré en la superposición, pero lo hace.
Básicamente, solo quiero saber cuándo alguien hace clic en el fondo negro de la superposición. ¿Hay alguna forma de hacer esto con la forma en que tengo mi código actualmente?
const overlay = document.querySelector('.overlay') overlay.onclick = function() { console.log('click on overlay!') } body { margin: 0; } .overlay { position: fixed; top: 0; left: 0; background-color: rgba(0,0,0,0.5); width: 100%; height: 100%; z-index: 10; } .content { width: 200px; height: 200px; position: absolute; z-index: 11; top: calc(50% - 100px); left: calc(50% - 100px); background: white; display: flex; align-items: center; justify-content: center; } <div class="overlay"> <div class="content">Hello World</div> </div>puede deshabilitar el evento de clic para la div de contenido
const content = document.querySelector('.content'); content.off('click');Para resolver este problema tuyo, debes comprender cómo funcionan los eventos de javascript. Hay tres fases del evento:
Fase de captura:
Cuando activa algún evento, JavaScript comienza a manejarlo al pasar del elemento superior (Ventana) a los elementos secundarios. Ocurre hasta que se alcanza el elemento target( .content ). En su caso, el evento pasa por el elemento .overlay pero el controlador de eventos no se activa porque, de forma predeterminada, todos los detectores de eventos se activan en la fase bubbling or target .
Fase objetivo:
El evento ha llegado al destino del evento. El mismo elemento en el que se activó el elemento, que en su caso es .content
Fase de burbujeo:
El evento se propaga hacia arriba a través de los ancestros del destino en orden inverso, comenzando con el padre y finalmente llegando a la ventana que lo contiene. Durante esta fase, su evento pasa por el elemento .overlay e invoca el controlador de eventos que se registró.
No sé cuál es la mejor solución para su problema, pero se puede resolver de varias maneras:
Solución propuesta por @PsiKai y @Joulss donde está verificando el elemento de destino por nombre de clase. Oyente de eventos registrado
Solución propuesta por @eMentorship. Al cambiar el marcado, el evento en la fase burbujeante no toca el elemento .overlay .
const content = document.querySelector('.element'); content.addEventListener('click', event => event.stopPropagation()); Al llamar a stopPropagation , evita que el evento vaya al elemento principal y, como resultado, el controlador de eventos .overlay se ignora como un evento que no se propaga al elemento raíz.
Fase de evento: https://developer.mozilla.org/en-US/docs/Web/API/Event/eventPhase
PD. Según MDN: el método addEventListener() es la forma recomendada de registrar un detector de eventos. Los beneficios son los siguientes:
Simplemente reestructure su código HTML y funcionará bien, ya que ya configuró el z-index para la superposición y el contenido también. así que como el contenido tiene un z-index más alto que la superposición, el contenido lo ocultará.
Manifestación:
const overlay = document.querySelector('.overlay') overlay.onclick = function() { console.log('click on overlay!') } body { margin: 0; } .popup { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 10;; } .overlay { position: fixed; top: 0; left: 0; background-color: rgba(0,0,0,0.5); width: 100%; height: 100%; z-index: 10; } .content { width: 200px; height: 200px; position: absolute; z-index: 11; top: calc(50% - 100px); left: calc(50% - 100px); background: white; display: flex; align-items: center; justify-content: center; } <div class="popup"> <div class="overlay"></div> <div class="content">Hello World</div> </div>