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

↘锁芯ラ 提交于 2019-11-26 19:44:47
user213788

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

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/

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.

Sergiu

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

pmrotule

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.

Felix

Korayem's solution works for me in 100% cases in modern Chrome, Safari, in 95% cases in Firefox, but does not work in Opera and IE.

I improved it a bit:

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

CSS:

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

html.notbusy, html.notbusy * {
    cursor: default !important;
}

Now it works in 100% cases in Chrome, Safari, Firefox and Opera. I do not know what to do with IE :(

Working solution on CodeSandbox

Some of the other solutions do not work in all circumstances. We can achieve the desired result with two css rules:

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

.not-busy {
  cursor: auto;
}

The former indicates that we are busy and applies to all elements on the page, attempting to override other cursor styles. The latter applies only to the page body and is used simply to force a UI update; we want this rule to be as non-specific as possible and it doesn't need to apply to other page elements.

We can then trigger and end the busy state as follows:

function onBusyStart() {
    document.body.classList.add('busy');
    document.body.classList.remove('not-busy');
}

function onBusyEnd() {
    document.body.classList.remove('busy');
    document.body.classList.add('not-busy');
}

In summary, although we have to change the cursor style to update the cursor, directly modifying document.body.style.cursor or similar does not have the intended effect, on some engines such as Webkit, until the cursor is moved. Using classes to affect the change is more robust. However, in order to reliably force the UI to update (again, on some engines), we have to add another class. It seems removing classes is treated differently from adding them.

I don't think you'll be able to do it.

However, try changing the scroll position; it might help.

HERE is my solution:

function yourFunc(){

$('body').removeClass('wait'); // this is my wait class on body you can $('body').css('cursor','auto');
$('body').blur();
$('body').focus(function(e){
$('body')
 .mouseXPos(e.pageX + 1)
 .mouseYPos(e.pageX - 1);
});

}

As of jquery 1.9 you should ajaxStart and ajaxStop to document. They work fine for me in firefox. Have not tested in other browsers.

In CSS:

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

In javaScript:

// Makes the mousecursor show busy during ajax 
// 
$( document )

   .ajaxStart( function startBusy() { $( 'html' ).addClass   ( 'busy' ) } )     
   .ajaxStop ( function stopBusy () { $( 'html' ).removeClass( 'busy' ) } )

Try using the correct css value for the cursor property:

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

http://www.w3schools.com/CSS/pr_class_cursor.asp

It's probably a bug in WebKit; you should report it.

I haven't tried this, but what about if you create a transparent div that is absolutely positioned and fills the viewport just before changing the CSS. Then, when the css is changed on the body, remove the div. This might trigger a mouseover event on the body, which might cause the cursor to update to the latest CSS value.

Again, I haven't tested this, but it's worth a shot.

Hey Guys, I have a nitty gritty solution which works on all browsers. Assumption is protoype library is used. Someone can write this as plain Javascript too. The solution is to have a div on top of all just after you reset the cursor and shake it a little bit to cause the cursor to move. This is published in my blog http://arunmobc.blogspot.com/2011/02/cursor-not-changing-issue.html.

$('*').css('cursor','wait'); will work everywhere on the page including links

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!