I have a simple overlay that I want to catch click events on. Problem is, I don't want any clicks that occur within the content of the overlay to trigger an event. For example, if you look at my code snippet below, clicking inside the .content
div should not trigger the click event listener that I set on the overlay, but it does.
Basically I want to just know when someone clicks the black background of the overlay. Is there anyway to do this with how I currently have my code?
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>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
you can disable the click event for the content div
const content = document.querySelector('.content');
content.off('click');
CodePudding user response:
Access the event target in the arguments of your function. From there use a conditional if
statement to ensure that the target clicked is the overlay, and only do your action if the condition is true.
const overlay = document.querySelector('.overlay')
overlay.onclick = function(e) {
if (e.target.classList.contains("overlay")) {
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>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
@PsiKai solution is good. You can also handle it with
I don't know what is best solution for your problem but it can be solved in several ways:
Solution proposed by @PsiKai and @Joulss where you're checking target element by class name. Registered event listener
Solution proposed by @eMentorship. By changing the markup, event at bubbling phase doesn't touch
.overlay
element.
const content = document.querySelector('.element');
content.addEventListener('click', event => event.stopPropagation());
By calling stopPropagation
you stoping event from going to the parent element and as a result .overlay
event handler ignored as event not bubbling to the root element.
Event phase: https://developer.mozilla.org/en-US/docs/Web/API/Event/eventPhase
PS. According to MDN: The addEventListener()
method is the recommended way to register an event listener. The benefits are as follows:
- It allows adding more than one handler for an event. This is particularly useful for libraries, JavaScript modules, or any other
kind of code that needs to work well with other libraries or
extensions. - In contrast to using an onXYZ property, it gives you finer-grained control of the phase when the listener is activated (capturing vs. bubbling).
- It works on any event target, not just HTML or SVG elements.