Overload CSS `cursor: wait` page wide with jquery

04 December, 2018

Problem:

undefined

You probably want to tell users on your page to wait for something important that is happening in the background. Most likely performing asynchronous page calls, calculations, DOM manipulation etc...

But just like any CSS property, the nested elements override the parent's property. This is troublesome if you have a lot of buttons and custom cursors in your style.

Solution:

Now there are many solutions to find on the internet to tackle this problem. But most of these suggest working with expensive javascript functions to change every nested element's cursor property, and returning them to the original value when done.

My solution however is far more simpler than that, we will create a fake transparent second body with a div to overlay the page.

Create a new div

Right before the body closing tag (</body>). Insert a new div element with the class window.

<div class="window"></div>

Define some CSS

.window {
    display: none;      /* Hide the div                                     */
    position: fixed;    /* Set the position relative to the top left corner */
    z-index: 1000;      /* Put the element in the foreground                */
    top: 0;left: 0;     /* Set the position                                 */
    height: 100%;       /* Make the div full screen                         */
    width:100%;         /*                                                  */
    opacity: 0;         /* Make the div transparent                         */
    cursor: wait;       /* Our beloved cursor                               */
}

body.loading .window {  /* If the body tag has the class loading then set   */
                        /* the following properties of the window class.    */
    display: block;     /* Show the div                                     */
    overflow: hidden;   /* Hide any scrollbars for aesthetics               */
}

Option one: jquery

To activate the page wide loading cursor in custom functions use the following lines.

$("body").addClass("loading");      // enable the loading cursor
$("body").removeClass("loading");   // disable the cursor

If you wish that all your AJAX calls made with jquery automatically start the page wide loading cursor, you can use the following code.

$(document).ready(function() {
    $(document).ajaxStart(function() {
        $("body").addClass("loading");
    });
    $(document).ajaxComplete(function() {
        $("body").removeClass("loading");
    });
});

Option two: pure javascript 

To remove and add classes with the pure javacript body selector, use the following lines.

document.getElementsByTagName("BODY")[0].classList.add("loading");
document.getElementsByTagName("BODY")[0].classList.remove("loading");

Result and afterword

 undefined

(I added a black background color to the window class, and changed the opacity to 0.2 to dramatize the effect)

Now there is one hook to this solution, whenever the window is being displayed, the users on your page won't be able to interact with any of the elements which lay underneath the z-index of the window. However using the cursor wait would imply that your users shouldn't be interacting with any elements anyway, and this solution blocks them from doing so.

As you may have noticed the animation of the cursor wasn't able to be picked up by (different) screen recorders.