将浏览器光标从“等待”变为“自动”,而无需用户移动鼠标


68

我使用此jQuery代码在Ajax调用期间将鼠标指针设置为其繁忙状态(沙漏)。

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

并使用相应的代码将其设置为正常...

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

在某些浏览器上工作正常。

在Firefox和IE上,只要执行命令,鼠标光标就会改变。这是我想要的行为。

在Chrome和Safari上,除非用户移动指针,否则鼠标光标不会从“忙”变为“自动”。

使勉强的浏览器切换鼠标指针的最佳方法是什么?


Chrome:这为我做到了:stackoverflow.com/a/561397/511438
Valamas 2014年

如下@ j-allen所述,关闭开发人员工具/控制台后,此问题已在Chrome v50 +中修复。
ErikusMaximus

Answers:


36

目前,这两种浏览器均存在错误。两个链接上的更多详细信息(以及评论):

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

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


2
Bug于2009年报告,至今尚未确认。伤心。
StriplingWarrior

2
感谢您的链接。第一个链接提供了一些有用的注释,包括#87(code.google.com/p/chromium/issues/detail?id=26723#c87),这是我现在正在使用的解决方法
Greg Jackman

9
对于现在遇到此问题的人,尽管该漏洞显然已在2013年修复,但有时仍会在开发人员工具打开时发生(请参阅有关2016年12月以来的chrome bug 26723的评论)。因此,像您的用户一样拥有紧密的开发工具,然后一切都会好起来:)
Tim Malone

1
@TimMalone这是开发工具的特定问题。bugs.chromium.org/p/chromium/issues/detail?id=676644
Coburn

3
2017年

38

我宁愿这样优雅地做:

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

CSS:

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

资料来源:http : //postpostmodern.com/instructional/global-ajax-cursor-change/


2
Korayem-+1。不错的清洁方法。我昵称它代替了我拼凑的相当凌乱的实现。谢谢!!;-)
Jim Tollan 2011年

2
对于我的用例,我必须将此逻辑放入1毫秒的setTimeout中才能使其生效
jedierikb

14
这实际上并不能回答问题。如果不移动鼠标,则删除该类时光标不会变回自动。
格雷格·杰克曼

我喜欢这种解决方案,但是我需要将事件绑定到$(document),然后将类添加到$('html)才能使其正常工作。
扎克·格林伯格

23

我认为此问题(包括mousedown问题)现在已在Chrome 50中修复。

但前提是您不使用开发人员工具!

关闭工具,光标应立即响应。


4
哈,不会考虑关闭开发人员工具。谢谢!
ykay说,请

那就是关键:关闭开发人员工具!
Bobort

仍未在Chrome 60中修复
Seabizkit

1
只是为了清楚,如果您重新加载页面即location.reload();其不固定。真的很烦。。。所以在ajax调用中完成了location.reload();。并且光标将是错误的。
Seabizkit

也未在63.0.3239.108(正式版本)(64位)中
修复

7

我从Korayem解决方案中得到启发。

Javascript:

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

CSS:

.busy * {
    cursor: wait !important;
}

在Chrome,Firefox和IE 10上进行了测试。无需移动鼠标即可更改光标。IE10需要“!important”。

编辑:AJAX请求完成后,您仍然必须在IE 10上移动光标(因此,出现普通光标)。等待光标出现而无需移动鼠标。


1
并确保开发工具已关闭!
Bobort

1

首先,您应该意识到,如果您将光标分配给体内的任何标签,$('body').css('cursor', 'wait');都不会更改该标签的光标(像我一样,我cursor: pointer;在所有锚标签上使用)。您可能想先看看我对这个特定问题的解决方案:光标等待ajax调用

正如其他人所说,对于仅在用户在Webkit浏览器上移动鼠标后才更新光标的问题,没有真正的解决方案。

话虽如此,如果您将css微调器动态地添加到当前光标,仍然存在解决方法。这不是一个完美的解决方案,因为您不确定光标的大小以及旋转器是否正确定位。

光标后的CSS微调器: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);

您还需要检查它是否也是触摸设备 var isTouchDevice = typeof window.ontouchstart !== 'undefined';

总之,您最好尝试在页面中添加静态微调器或其他可以显示加载过程的控件,而不要尝试使用游标进行操作。


1

Korayem的解决方案在现代Chrome,Safari中100%的情况下对我有效,在Firefox中95%的情况下对我有效,但在Opera和IE中不起作用。

我做了一些改进:

$('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;
}

现在,它可以在Chrome,Safari,Firefox和Opera中100%使用。我不知道该如何处理IE :(


1

CodeSandbox上的工作解决方案

其他一些解决方案并非在所有情况下都有效。我们可以使用两个CSS规则来达到预期的结果:

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

.not-busy {
  cursor: auto;
}

前者表示我们很忙,并应用于页面上的所有元素,试图覆盖其他光标样式。后者仅适用于页面正文,仅用于强制UI更新。我们希望此规则尽可能不具体,并且不需要将其应用于其他页面元素。

然后我们可以触发并结束繁忙状态,如下所示:

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');
}

总而言之,尽管我们必须更改游标样式以更新游标document.body.style.cursor,但是在某些组件(例如Webkit)上,直接移动或直接修改游标并不会产生预期的效果,直到游标被移动为止。使用类来影响更改更加健壮。但是,为了可靠地强制UI更新(再次在某些引擎上),我们必须添加另一个类。删除类似乎与添加类不同。


在Chrome 70上,该解决方案不适用于我。光标一直保持等待状态,直到移动鼠标为止。
菲尔B

1
@PhilB奇怪。它可以在Windows 10上的Chrome 70.0.3538.77上为我工作。
Ninjakannon

我在Windows 7上,是否可以有所作为?:/
Phil B

@PhilB可能做得很好,也许因此可以提供多种解决方案。我会对此保持开放的
态度

1
好的,我做了一些测试,并且(如其他提到的那样)似乎只能在开发工具打开的情况下重现该问题。我猜对我有好处。反正可以解决。:)
Phil B

0

我认为您将无法做到。

但是,尝试更改滚动位置。它可能会有所帮助。


3
试过了。尝试了很多改动。它们都不足以胜任Chrome或Safari。似乎很蠢。如果光标显示等待,用户为什么要触摸鼠标?
Nosredna,2009年

0

这里是我的解决方案:

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);
});

}

0

从jquery 1.9开始,您应该使用ajaxStart和ajaxStop来记录文档。他们对我来说很好用Firefox。尚未在其他浏览器中进行过测试。

在CSS中:

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

在javaScript中:

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

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



-1

我还没有尝试过,但是如果您创建一个绝对定位并在更改CSS之前填充视口的透明div呢?然后,在主体上更改CSS时,删除div。这可能会触发身体上的鼠标悬停事件,这可能导致光标更新为最新的CSS值。

同样,我还没有测试过,但是值得一试。


我尝试了许多时髦的事情,浏览器似乎都忽略了它们。但是,如果我有时间,我会尝试你的。
Nosredna

2
我也有全尺寸叠加层的相同问题,并且当不移动时,光标不会改变。
Omiod


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.