Getting the browser cursor from "wait" to "auto" without the user moving the mouse

45,871

Solution 1

It is a bug in both browsers at the moment. More details at both links (in comments as well):

http://code.google.com/p/chromium/issues/detail?id=26723

and

http://code.google.com/p/chromium/issues/detail?id=20717

Solution 2

I would rather do it more elegantly like so:

$(function(){  
  $("html").bind("ajaxStart", function(){  
     $(this).addClass('busy');  
   }).bind("ajaxStop", function(){  
     $(this).removeClass('busy');  
   });  
});

CSS:

html.busy, html.busy * {  
  cursor: wait !important;  
}  

Source: http://postpostmodern.com/instructional/global-ajax-cursor-change/

Solution 3

I believe this issue (including the mousedown problem) is now fixed in Chrome 50.

But only if you are not using the developer tools!!

Close the tools and the cursor should immediately respond better.

Solution 4

I got inspired from Korayem solution.

Javascript:

jQuery.ajaxSetup({
    beforeSend: function() {
       $('body').addClass('busy');
    },
    complete: function() {
       $('body').removeClass('busy');
    }
});

CSS:

.busy * {
    cursor: wait !important;
}

Tested on Chrome, Firefox and IE 10. Cursor changes without moving the mouse. "!important" is needed for IE10.

Edit: You still have to move cursor on IE 10 after the AJAX request is complete (so the normal cursor appear). Wait cursor appears without moving the mouse..

Solution 5

First of all, you should be aware that if you have a cursor assigned to any tag within your body, $('body').css('cursor', 'wait'); will not change the cursor of that tag (like me, I use cursor: pointer; on all my anchor tag). You might want to look at my solution to this particular problem first : cursor wait for ajax call

For the problem that the cursor is only updated once the user move the mouse on webkit browsers, as other people said, there is no real solution.

That being said, there is still a workaround if you add a css spinner to the current cursor dynamically. This is not a perfect solution because you don't know for sure the size of the cursor and if the spinner will be correctly positioned.

CSS spinner following the cursor: DEMO

$.fn.extend(
{
    reset_on : function(event_name, callback)
    { return this.off(event_name).on(event_name, callback); }
});

var g_loader = $('.loader');

function add_cursor_progress(evt)
{
    function refresh_pos(e_)
    {
        g_loader.css({
            display : "inline",
            left : e_.pageX + 8,
            top : e_.pageY - 8
        });
    }
    refresh_pos(evt);
    var id = ".addcursorprog"; // to avoid duplicate events

    $('html').reset_on('mousemove' + id, refresh_pos);

    $(window).
    reset_on('mouseenter' + id, function(){ g_loader.css('display', 'inline'); }).
    reset_on('mouseleave' + id, function(){ g_loader.css('display', 'none'); });
}

function remove_cursor_progress(evt)
{
    var id = ".addcursorprog";
    g_loader.css('display', 'none');

    $('html').off('mousemove' + id);
    $(window).off('mouseenter' + id).off('mouseleave' + id);
}

$('.action').click(add_cursor_progress);
$('.stop').click(remove_cursor_progress);

You will need to check if it is a touch device as well var isTouchDevice = typeof window.ontouchstart !== 'undefined';

In conclusion, you better try to add in your page a static spinner or something else that shows the loading process instead of trying to do it with the cursor.

Share:
45,871
Nosredna
Author by

Nosredna

I can clap with one hand. I got married in Mick Fleetwood's pants. Gregg Keizer once had me edit an Orson Scott Card column. A game Sega published was based on a dream I had. I have an officially licensed Star Trek tunic from before the first film! Anyone know what that's worth? Senior Software Engineer, Playdom

Updated on July 05, 2022

Comments

  • Nosredna
    Nosredna almost 2 years

    I use this jQuery code to set the mouse pointer to its busy state (hourglass) during an Ajax call...

    $('body').css('cursor', 'wait');
    

    and this corresponding code to set it back to normal...

    $('body').css('cursor', 'auto');
    

    This works fine... on some browsers.

    On Firefox and IE, as soon as I execute the command, the mouse cursor changes. This is the behavior I want.

    On Chrome and Safari, the mouse cursor does not visibly change from "busy" to "auto" until the user moves the pointer.

    What is the best way to get the reluctant browsers to switch the mouse pointer?

  • Nosredna
    Nosredna over 14 years
    Yeah, sorry. That's a typo. I am using (and having trouble with) "wait", not "busy".
  • Nosredna
    Nosredna over 14 years
    Tried that. Tried lots of alterations. None of them were sufficient kicks to Chrome or Safari. Seems dumb. Why would the user want to touch the mouse if the cursor is showing wait?
  • Nosredna
    Nosredna over 14 years
    I've tried many funky things, and the browsers seem to ignore them all. But if I get time, I'll try yours.
  • Omiod
    Omiod about 14 years
    I have the same problem with a full size overlay too, and the cursor doesn't change, when not moved.
  • jim tollan
    jim tollan about 13 years
    Korayem - +1. nice clean approach. i nicked it as a replacement for a rather messy implementation that i had cobbled together. thanks!! ;-)
  • StriplingWarrior
    StriplingWarrior over 12 years
    Bug reported in 2009, and still unconfirmed. Sad.
  • jedierikb
    jedierikb about 11 years
    for my use case, I had to put this logic into a setTimeout of 1 millisecond to get it to take effect
  • Greg Jackman
    Greg Jackman almost 11 years
    thanks for the links. The first link has some useful comments, including #87 (code.google.com/p/chromium/issues/detail?id=26723#c87) which is the workaround I'm now using
  • Greg Jackman
    Greg Jackman almost 11 years
    This doesn't actually answer the question. If you don't move the mouse, the cursor doesn't change back to auto when you remove the class.
  • Zach Greenberger
    Zach Greenberger almost 11 years
    I like this solution, but I needed to bind the event to $(document), and then add the class to $('html) to get it to work.
  • Camilo Martin
    Camilo Martin over 10 years
    Applying that to ALL elements?? Not gonna happen. And doesn't fix the bug either.
  • Clr
    Clr about 9 years
    This code works for me. myDiv.scrollLeft +=1; myDiv.scrollLeft -1; code.google.com/p/chromium/issues/detail?id=26723#c32
  • Adam Smith
    Adam Smith almost 8 years
    This doesn't overcome the bug.
  • ykay says Reinstate Monica
    ykay says Reinstate Monica almost 8 years
    Ha, wouldn't have thought of closing developer tools. Thanks!
  • Tim Malone
    Tim Malone over 7 years
    For people coming across this now, although the bug was apparently fixed in 2013, it still sometimes occurs when dev tools is open (see the comments on the chromium bug 26723 from Dec 2016). So, close dev tools like your users will have, and then all good :)
  • Bobort
    Bobort over 7 years
    That is the key: close developer tools!
  • Bobort
    Bobort over 7 years
    And make sure the development tools are closed!
  • Cobertos
    Cobertos about 7 years
    @TimMalone This is the specific issue for the dev tools thing. bugs.chromium.org/p/chromium/issues/detail?id=676644
  • Le-roy Staines
    Le-roy Staines almost 7 years
    @TimMalone WOW. Thanks.
  • Seabizkit
    Seabizkit over 6 years
    Still happening in 2017/08/20 chrome 60, with or without dev tools open
  • Seabizkit
    Seabizkit over 6 years
    still not fixed in chrome 60
  • Seabizkit
    Seabizkit over 6 years
    just to be clear its not fixed if you reload the page i.e. location.reload(); really annoying... so in the ajax call when done do location.reload(); and the cursor will be wrong.
  • Rob Audenaerde
    Rob Audenaerde over 6 years
    Not fixed in 63.0.3239.108 (Official Build) (64-bit) as well :(
  • Phil B
    Phil B over 5 years
    Still happening for me on v70.0.3538.77 - wow this is really a long time bug. Same as OP, it works fine on FF/IE it is just Chrome that doesn't update cursor until the mouse is moved.
  • Phil B
    Phil B over 5 years
    Solution does not work for me on Chrome 70. The cursor stays as wait cursor until the mouse is moved.
  • Ninjakannon
    Ninjakannon over 5 years
    @PhilB Strange. It is working for me on Chrome 70.0.3538.77 on Windows 10. I have also successfully deployed this solution across dozens of environments including both Windows and MacOS with no such bug report yet.
  • Phil B
    Phil B over 5 years
    I'm on Windows 7, if that could make some difference? :/
  • Ninjakannon
    Ninjakannon over 5 years
    @PhilB It may well do, perhaps hence the variety of solutions. I will keep an eye open for this
  • Phil B
    Phil B over 5 years
    Ok I did a little more testing and it seems (as other mentioned) that I can only reproduce the issue with dev tools open. Good for me I guess. Solution ok anyways. :)
  • Nick De Beer
    Nick De Beer over 5 years
    Also seeing this bug on v70.0.3538.7 when devtools is open. Closing and opening devtools again sorts out the problem.
  • pailhead
    pailhead over 5 years
    I'm doing this with react, setting the body to "grab". It doesn't update even while moving, only when i rest and do mouse up. At this point it should actually be "default" and it shows in the dev tools, but not in the view. Closing the devtools just straight up fixes the issue!
  • Rivenfall
    Rivenfall almost 5 years
    A few tips: right click on the refresh button for different options. And see the Memory tab to check if the Memory gets lower when you refresh. It seems memory can be kept between reloads until the tab is closed.
  • chrisan
    chrisan over 3 years
    Why is this still a thing?! I was losing my mind trying to figure out why my code wasnt working. Closed devtools and it worked right away
  • ArthurKa
    ArthurKa about 2 years
    Still not fixed in Chrome v100.