I have this simple code
const readmore = document.getElementById("read");
const modaloverlay = document.getElementById("modaloverlay");
const closeButton = document.querySelector(".closebutton");
readmore.addEventListener("click", function () {
modaloverlay.classList.add("overlayshows");
});
closeButton.addEventListener("click", function () {
modaloverlay.classList.remove("overlayshows");
});
window.addEventListener('click', function(e){
if ((modaloverlay.classList.contains("overlayshows")) && (e.target != modaloverlay)) {
modaloverlay.classList.remove("overlayshows");
}
});
.overlay {
background: rgba(0,0,0,.9);
padding: 20px;
position: fixed;
top: 10px;
bottom: 10px;
left: 0;
right: 0;
align-items: center;
justify-content: center;
display: none;
max-width: 600px;
margin: 0 auto;
color: #fff
}
.overlayshows {
display: block;
}
.closebutton {
cursor: pointer;
float: right;
}
<div >
<h1>Content</h1>
<button id="read">READ MORE</button>
</div>
<div id="modaloverlay">
<span >X</span>
<div >
Morecontent
</div>
</div>
When i click the button the modal is opened, this part is easy; i know that if i remove the last part of js it will work, but i want that if you click out the modal, the modal is closed, i dont know what is wrong. Thanks :)
CodePudding user response:
W3schools has a good tutorial on modals: https://www.w3schools.com/howto/howto_css_modals.asp
The code is as follows for closing a modal if a user clicks outside of it:
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
CodePudding user response:
This solution creates a modal singleton to make it easier to manage the lifecycle of the component. It also uses event delegation for easy event management. The key problem with your solution was not preventing the modal click event from propagating.
const modal = {
CLASSES: {
SHOW: 'overlayshows',
CLOSE_BUTTON: 'closebutton',
MODAL: 'modaloverlay',
READ: 'read'
},
isVisible: false,
el: document.getElementById("modaloverlay"),
initialize() {
modal.addEvents();
},
show() {
modal.el.classList.add(modal.CLASSES.SHOW);
modal.isVisible = true;
},
hide() {
modal.el.classList.remove(modal.CLASSES.SHOW);
modal.isVisible = false;
},
addEvents() {
modal.removeEvents();
modal.el.addEventListener('click', modal.eventHandlers.onModalClick);
window.addEventListener('click', modal.eventHandlers.onWindowClick);
},
removeEvents() {
modal.el.removeEventListener('click', modal.eventHandlers.onModalClick);
window.removeEventListener('click', modal.eventHandlers.onWindowClick);
},
eventHandlers: {
onModalClick(event) {
event.stopImmediatePropagation();
if (!event.target) {
return;
}
if (event.target.classList.contains(modal.CLASSES.CLOSE_BUTTON)) {
modal.hide();
}
},
onWindowClick(event) {
if (event.target.classList.contains(modal.CLASSES.READ)) {
modal.show();
} else {
modal.hide();
}
}
}
}
modal.initialize();