Reputation: 261
I've a Simple javascript modal that I've collected from W3 Schools. It's easy and light. But the fact is, when I click on modal button, it appears with slide up animation and also an overlay animation. But when click on close button or click outside, modal get disappear or close without any animation. I want to add an animation on modal closing time. That's mean, there will be an animation on Both, modal appear and disappearing time. With overlay, like appear time. How can Indo it....?
// Get the modal
var modal = document.getElementById("myModal");
// Get the button that opens the modal
var btn = document.getElementById("myBtn");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks the button, open the modal
btn.onclick = function() {
modal.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
/* The Modal (background) */
.modal {
display: none;
/* Hidden by default */
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(0, 0, 0);
/* Fallback color */
background-color: rgba(0, 0, 0, 0.4);
/* Black w/ opacity */
-webkit-animation-name: fadeIn;
/* Fade in the background */
-webkit-animation-duration: 0.4s;
animation-name: fadeIn;
animation-duration: 0.4s
}
/* Modal Content */
.modal-content {
position: fixed;
bottom: 0;
background-color: #fefefe;
width: 100%;
-webkit-animation-name: slideIn;
-webkit-animation-duration: 0.4s;
animation-name: slideIn;
animation-duration: 0.4s
}
/* The Close Button */
.close {
color: white;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
.modal-header {
padding: 2px 16px;
background-color: #5cb85c;
color: white;
}
.modal-body {
padding: 2px 16px;
}
.modal-footer {
padding: 2px 16px;
background-color: #5cb85c;
color: white;
}
/* Add Animation */
@-webkit-keyframes slideIn {
from {
bottom: -300px;
opacity: 0
}
to {
bottom: 0;
opacity: 1
}
}
@keyframes slideIn {
from {
bottom: -300px;
opacity: 0
}
to {
bottom: 0;
opacity: 1
}
}
@-webkit-keyframes fadeIn {
from {
opacity: 0
}
to {
opacity: 1
}
}
@keyframes fadeIn {
from {
opacity: 0
}
to {
opacity: 1
}
}
<h2>Bottom Modal</h2>
<!-- Trigger/Open The Modal -->
<button id="myBtn">Open Modal</button>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-header">
<span class="close">×</span>
<h2>Modal Header</h2>
</div>
<div class="modal-body">
<p>Some text in the Modal Body</p>
<p>Some other text...</p>
</div>
<div class="modal-footer">
<h3>Modal Footer</h3>
</div>
</div>
</div>
Updated code:
// Get the modal
var modal = document.getElementById("myModal");
// Get the button that opens the modal
var btn = document.getElementById("myBtn");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks the button, open the modal
btn.onclick = function() {
modal.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
function closeModal() {
modal.classList.add('animate-out');
modal.addEventListener('animationend', function() {
modal.style.display = "none";
modal.classList.remove('animate-out');
}, {
once: true
});
}
span.onclick = closeModal;
window.onclick = function(event) {
if (event.target.closest('#myModal') === null) {
closeModal();
}
};
/* The Modal (background) */
.modal {
display: none;
/* Hidden by default */
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(0, 0, 0);
/* Fallback color */
background-color: rgba(0, 0, 0, 0.4);
/* Black w/ opacity */
-webkit-animation-name: fadeIn;
/* Fade in the background */
-webkit-animation-duration: 0.4s;
animation-name: fadeIn;
animation-duration: 0.4s
}
/* Modal Content */
.modal-content {
position: fixed;
bottom: 0;
background-color: #fefefe;
width: 100%;
-webkit-animation-name: slideIn;
-webkit-animation-duration: 0.4s;
animation-name: slideIn;
animation-duration: 0.4s
}
/* The Close Button */
.close {
color: white;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
.modal-header {
padding: 2px 16px;
background-color: #5cb85c;
color: white;
}
.modal-body {
padding: 2px 16px;
}
.modal-footer {
padding: 2px 16px;
background-color: #5cb85c;
color: white;
}
/* Add Animation */
@-webkit-keyframes slideIn {
from {
bottom: -300px;
opacity: 0
}
to {
bottom: 0;
opacity: 1
}
}
@keyframes slideIn {
from {
bottom: -300px;
opacity: 0
}
to {
bottom: 0;
opacity: 1
}
}
@-webkit-keyframes fadeIn {
from {
opacity: 0
}
to {
opacity: 1
}
}
@keyframes fadeIn {
from {
opacity: 0
}
to {
opacity: 1
}
}
.modal.animate-out {
animation-name: fadeOut;
}
.modal.animate-out .modal-content {
animation-name: slideOut;
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes slideOut {
from {
transform: translate3d(0, 300px, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
<h2>Bottom Modal</h2>
<!-- Trigger/Open The Modal -->
<button id="myBtn">Open Modal</button>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-header">
<span class="close">×</span>
<h2>Modal Header</h2>
</div>
<div class="modal-body">
<p>Some text in the Modal Body</p>
<p>Some other text...</p>
</div>
<div class="modal-footer">
<h3>Modal Footer</h3>
</div>
</div>
</div>
Upvotes: 1
Views: 1183
Reputation: 20944
The way your "in" animation works is by first changing the display
property to block
which renders the element visible. That also triggers the animation
that is set on the modal.
The "out" animation has to work in the reverse order. First you have to animate the modal out. Whenever the animation is finished change the display
property to none
.
First define the animation. It should be the reverse keyframes of fadeIn
and slideIn
.
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes slideOut {
from {
transform: translate3d(0, 300px, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
Also add a class that uses this animation. That way we can add the animation the .modal
to overwrite the style.
.modal.animate-out {
animation-name: fadeOut;
}
.modal.animate-out .modal-content {
animation-name: slideOut;
}
To trigger the animation you'll only need to add the animate-out
class we've just created to the modal once you click the close button. Then immediately add an event listener that listens for the animationend
event. This event will trigger whenever the animation has finished, which in this case is our fade out animation.
After it finishes set display
to none
and remove the animate-out
class from the modal to reset the animation so that a fade in can happen next time we show the modal. The { once: true }
part ensures that this event is only listened to once. This is important since there are multiple animations but we only want the display: none
and removal of the animate-out
class to happen on the fade out animation.
// Get the modal
var modal = document.getElementById("myModal");
// Get the button that opens the modal
var btn = document.getElementById("myBtn");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks the button, open the modal
btn.onclick = function() {
modal.style.display = "block";
}
function closeModal() {
modal.classList.add('animate-out');
modal.addEventListener('animationend', function() {
modal.style.display = "none";
modal.classList.remove('animate-out');
}, { once: true });
}
span.onclick = closeModal;
document.onclick = function(event) {
if (event.target.matches('#myModal')) {
closeModal();
}
};
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.4);
animation-name: fadeIn;
animation-duration: 0.4s
}
.modal.animate-out {
animation-name: fadeOut;
}
.modal-content {
position: fixed;
bottom: 0;
background-color: #fefefe;
width: 100%;
animation-name: slideIn;
animation-duration: 0.4s
}
.modal.animate-out .modal-content {
animation-name: slideOut;
}
.close {
color: white;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
.modal-header {
padding: 2px 16px;
background-color: #5cb85c;
color: white;
}
.modal-body {
padding: 2px 16px;
}
.modal-footer {
padding: 2px 16px;
background-color: #5cb85c;
color: white;
}
@keyframes slideIn {
from {
transform: translate3d(0, 300px, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes slideOut {
from {
transform: translate3d(0, 0, 0);
}
to {
transform: translate3d(0, 300px, 0);
}
}
@keyframes fadeIn {
from {
opacity: 0
}
to {
opacity: 1
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<h2>Bottom Modal</h2>
<!-- Trigger/Open The Modal -->
<button id="myBtn">Open Modal</button>
<!-- The Modal -->
<div id="myModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<span class="close">×</span>
<h2>Modal Header</h2>
</div>
<div class="modal-body">
<p>Some text in the Modal Body</p>
<p>Some other text...</p>
</div>
<div class="modal-footer">
<h3>Modal Footer</h3>
</div>
</div>
</div>
Upvotes: 2