Reputation: 177
I am trying to close the modal when it's clicked outside. I have tried to loop through modals but can't get them to set its display to none.
Here is my HTML:
<div class="projects">
<div data-modal="modal1">
<div>
<p>Coffee</p>
</div>
<img src="img/coffee.png" alt="">
</div>
<div data-modal="modal2">
<div>
<p>Tea</p>
</div>
<img src="img/tea.png" alt="">
</div>
</div>
<div class="project-card" id="modal1">
<button class="close">X</button>
<div class="overlay">
<img src="img/coffee.png" alt="">
</div>
</div>
<div class="project-card" id="modal2">
<button class="close">X</button>
<div class="overlay">
<img src="img/tea.png" alt="">
</div>
</div>
Here is my code to open modals.
const coffeeGrounds = document.querySelectorAll('.projects > div[data-modal^=modal]');
for (var i = 0; i < coffeeGrounds.length; i++) {
coffeeGrounds[i].addEventListener('click', function () {
var x = this.getAttribute('data-modal');
var a = document.getElementById(x);
a.setAttribute('style','display:block');
});
}
Here is my code, when clicked outside to close the modal:
window.addEventListener('click',function(){
for(var i = 0; i<coffeeGrounds.length; i++){
var x = coffeeGrounds[i].getAttribute('data-modal');
var a = document.getElementById(x);
console.log(a);
if(a.style.display === 'block'){
a.setAttribute('style','display:none');
}
}
});
Over here by setting the modal display to none. It's holding back to display the modal also.
Please any help would be appreciated.
Codepen: https://codepen.io/zaidik/pen/bGwpzbE
Upvotes: 1
Views: 5454
Reputation: 21
Replying to the accepted answer, by Eugensunic
window.addEventListener('click', function(e) {
const allModals = document.querySelectorAll('.project-card');
//e.path is deprecated
// use instead e.composedPath() like this:
let paths = e.composedPath()
if (!paths.some(x => x.className && x.className.includes('project-card'))) {
allModals.forEach(x => x.style.display = 'none');
}
}, true)
Upvotes: 0
Reputation: 13723
When you click outside of the modal window you should not have the modal window in you event propagation array
In other words take advantage of event.path property
Working example (based on the provided fiddle)
window.addEventListener('click', function(e) {
const allModals = document.querySelectorAll('.project-card');
if (!e.path.some(x => x.className && x.className.includes('project-card'))) {
allModals.forEach(x => x.style.display = 'none');
}
}, true)
Working fiddle example: https://jsfiddle.net/7pzs1042/
Upvotes: 3