Reputation: 207
I'm trying to close an overlay window by clicking on the outer body only. The problem is that the overlay get closed even if I click on the overlay panel itself and if I click on any other element i put in it (divs, buttons, icons etc etc...) I don't know how to target only the body around the overlay and not the overlay window itself. Can you please help?
Here is both html markup and related JS.
<div id="main">
<div class"other-content">
<!-- other content -->
</div>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal__content">
<!-- some content - divs, buttons etc etc -->
</div>
</div>
</div>
$(document).on('click',"#myModal", function(e) {
$('#myModal').fadeOut();
});
Upvotes: 1
Views: 17735
Reputation: 20034
As my understanding you are styling:
Please try the below code to detect where user are clicking in, inside or outside the modal-content.
(function ($) {
$('.modal').on('click', function (e) {
//Check whether click on modal-content
if (e.target !== this)
return;
$(this).fadeOut();
});
})(jQuery);
Upvotes: 5
Reputation:
You are adding an .on('click'...)
to the whole document, I would just add another layer div that acts as a background and a trigger.
Everbody here is thinking too complicated I think, (despite the fact, that the stuff about event bubbling etc. is correct).
Since you have asked for an alternative, this is how I do it:
<!DOCTYPE html>
<html>
<style>
body {
background: #fff;
font-family: 'Arial', sans-serif;
color: #888;
}
#main {
width: 960px;
height: 600px;
margin: auto;
border: 1px solid #555;
padding: 20px;
}
.other-content {
background: #f1f1f1;
border: 1px solid #f6f6f6;
padding: 20px;
}
#myModal {
display: none;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
background: #545454;
}
.modal-inner-content {
width: 300px;
margin: 10% auto 0 auto;
color: #666;
padding: 20px;
background: white;
}
</style>
<script>
// All pure, beautiful Vanilla JS
// This is only dumb toggle.. 1 and 0
function toggleModalWindow() {
// For scrollbar Handling
var body = document.getElementById('top')
// first, grab the id of the outer modal window
var modal = document.getElementById('myModal');
// Then get the "status" (open or closed) of that previously declared variable
var status = modal.getAttribute('data-status');
// Now we do simple if check if it is open or closed
if(status === 'closed') {
// Make the modal block, then manipulate it's opacity slowly
modal.style.display = "block";
// We hide the browser sidebar
body.style.overflowY = "hidden";
// don't forget to set the attributes again
modal.setAttribute('data-status', 'open');
} else {
modal.style.display = "none";
// show browser sidebar again
body.style.overflowY = "visible";
// don't forget to set the attributes again
modal.setAttribute('data-status', 'closed');
}
}
</script>
</head>
<body id="top">
<div id="main">
<div class"other-content">
<h1>Awesome Content</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae saepe odio, labore ad, cum repudiandae non officia asperiores. Sequi porro magni corporis.</p>
</div>
<div class="other-content">
<button onclick="toggleModalWindow();">show me that badASs modal</button>
</div>
<!-- The Modal -->
<div id="myModal" class="modal" data-status="closed" onclick="toggleModalWindow();">
<!-- Modal content -->
<div class="modal__content">
<div class="modal-inner-content">
<h2>Modal Title</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum enim sapiente eius, asperiores ea mollitia velit accusamus soluta similique nobis modi obcaecati veritatis labore temporibus nulla, hic aliquid nam error!</p>
</div>
</div>
</div>
</div>
</body>
</html>
Upvotes: 0
Reputation: 207
Found a working solution. See below.
$(document).on('click',"#myModal", function(e) {
e.preventDefault();
if(e.target.id === "myModal"){
$('#myModal').fadeOut();
}
});
Upvotes: 2
Reputation: 10057
This is called event bubbling. Because the modal is a child of the document, when the modal is clicked, the event propagates to any parent listeners. This is the by design. To prevent this, you can use event.stopPropagation()
on the modal.
For example:
$( document ).on( 'click', function( event ) {
$( '#myModal' ).fadeOut();
});
$( '#myModal' ).on( 'click', function( event ) {
event.stopPropagation();
});
It's worth noting that by stopping event propagation, any events that are on parent elements of the modal will also be prevented.
Here is an example of a super basic modal. Honestly, though, you might benefit from looking at better modal design & integration. Having a variable to keep track of whether its open or not would be good. Additionally, an overlay in the background could serve as the only element to assign a listener to. I'm not saying this is the best way.
Upvotes: 5
Reputation: 20646
Use a click event on <body>
, with event.currentTarget
to check for elements.
$('body').on('click',function(e) {
var $currEl = $(e.currentTarget);
if(!$currEl.is('#myModal') && !$currEl.closest('#myModal').length){
$('#myModal').fadeOut();
}
else if(/write code element which triggers modal open even/){
$('#myModal').fadeIn(); //or any code to trigger modal open
}
});
$currEl.is('#myModal')
checks if the current clicked elements is myModal
$currEl.closest('#myModal').length
checks if the current element in inside/child of myModal
Upvotes: 1