JSFiddle - React, Tailwind, and code Playground
HTML
<hr>
<a href="#" class="btn">Trigger via Link</a>
<img src="http://www.bie.org/images/spinner.gif" class="spinner" alt="loading">
<hr>
<div class="log"></div>
CSS
body{
margin:10px;
}
a.btn{
display:inline-block;
color:green;
text-decoration:none;
padding:3px;
border:solid 1px green;
border-radius:3px;
background:lightgreen;
}
a.btn:hover{
opacity:.9;
}
a.btn.loading{
background:red
}
.spinner{
display:none;
height:18px;
width:18px;
}
JavaScript
/**
* Monitors all ajax events and displays a loading spinner while waiting for the server's response.
* Also adds a loading class to all "a.btn".
*/
$.ajaxMonitor = function() {
// keep track of # of active requests.
var active = 0;
$( document ).ajaxSend(function( event, jqXHR ) {
// use window.event so we can look at the ACTUAL event that "triggered" us
event = window.event || event;
var target = $( event.target ),
isBtn = false;
try {
// kaBOOM. jQury 1.8b2 can't do this if the target is a document.
isBtn = target.is( ".btn" );
} catch ( e ) {
$( ".log" ).append( "<div>" + e + "</div>" );
}
if ( isBtn ) {
target.addClass( "loading disabled" );
jqXHR.always(function() {
target.removeClass( "loading disabled" );
});
}
// display a loading spinner to our user.
// Gets removed on ajaxComplete
$( ".spinner" ).show();
active++;
}).ajaxComplete(function() {
active--;
if ( active === 0 ) {
$( ".spinner" ).hide();
}
});
};
$(function() {
// start watching ajax events
$.ajaxMonitor();
// trigger an ajax event right away; no DOM interaction.
// window.event.target === document
doAjax();
// trigger an ajax event via interaction with the DOM
// window.event.target === an anchor element
$( document ).on( "click", "a", function( event ) {
event.preventDefault();
doAjax();
});
/**
* Load data via $.ajax in order to trigger our global ajaxSend and ajaxComplete events.
*/
function doAjax() {
$.ajax( "/echo/json/", {
"type": "post",
"data": {
"delay": 1 // second
}
}).success( function( response, jqXHR ){
$( ".log"...