JSFiddle - React, Tailwind, and code Playground
HTML
<button onclick="showLoading()">Add Spinner</button>
<button onclick="hideLoading()">Remove Spinner</button>
CSS
/* The spinner */
@keyframes spinner {
to {transform: rotate(360deg);}
}
.spinner,
.spinner:before {
width: 20px;
height: 20px;
box-sizing: border-box;
}
.spinner:before {
content: '';
display: block;
border-radius: 50%;
border: 2px solid #ccc;
border-top-color: #333;
animation: spinner .6s linear infinite;
}
.spinner-absolute {
position: absolute;
top: 50%;
left: 50%;
margin-top: -10px;
margin-left: -10px;
}
/* Animations */
.spinner-add,
.spinner-remove {
animation-fill-mode: both;
animation-duration: .4s;
}
.spinner-add {
animation-name: spinner-add;
}
@keyframes spinner-add {
from {transform: scale(0);}
to {transform: scale(1);}
}
.spinner-remove {
animation-name: spinner-remove;
}
@keyframes spinner-remove {
to {transform: scale(0);}
}
JavaScript
var waitingMask = {
show: function addSpinner(el, static_pos)
{
var spinner = el.children('.spinner');
if (spinner.length && !spinner.hasClass('spinner-remove')) return null;
!spinner.length && (spinner = $('<div class="spinner' + (static_pos ? '' : ' spinner-absolute') + '"/>').appendTo(el));
animateSpinner(spinner, 'add');
},
hide: function removeSpinner(el, complete)
{
var spinner = el.children('.spinner');
spinner.length && animateSpinner(spinner, 'remove', complete);
},
animate: function animateSpinner(el, animation, complete)
{
if (el.data('animating')) {
el.removeClass(el.data('animating')).data('animating', null);
el.data('animationTimeout') && clearTimeout(el.data('animationTimeout'));
}
el.addClass('spinner-' + animation).data('animating', 'spinner-' + animation);
el.data('animationTimeout', setTimeout(function() { animation == 'remove' && el.remove(); complete && complete(); }, parseFloat(el.css('animation-duration')) * 1000));
}
}
function showLoading(){
return waitingMask.show($('body'));
}
function hideLoading(){
return waitingMask.hide($('body'));
}