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"...