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

Posted

技术标签:

【中文标题】无需用户移动鼠标即可将浏览器光标从“等待”变为“自动”【英文标题】:Getting the browser cursor from "wait" to "auto" without the user moving the mouse 【发布时间】:2010-12-15 15:52:04 【问题描述】:

我使用这个 jQuery 代码在 Ajax 调用期间将鼠标指针设置为忙碌状态(沙漏)...

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

和这个对应的代码把它设置回正常...

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

这很好用……在某些浏览器上。

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

在 Chrome 和 Safari 上,鼠标光标在用户移动指针之前不会明显地从“忙碌”变为“自动”。

让不情愿的浏览器切换鼠标指针的最佳方法是什么?

【问题讨论】:

Chrome:这是为我做的:***.com/a/561397/511438 正如@j-allen 所指出的,当开发者工具/控制台关闭时,此问题已在 Chrome v50+ 中得到修复。 尽管 Chrome 有 bug,我还是 found a solution, which I describe in my answer below. 【参考方案1】:

我宁愿这样做更优雅:

$(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/

【讨论】:

Korayem - +1。好干净的方法。我用它来代替我拼凑起来的一个相当混乱的实现。谢谢!! ;-) 对于我的用例,我必须将此逻辑放入 1 毫秒的 setTimeout 才能使其生效 这实际上并没有回答问题。如果你不移动鼠标,当你移除类时光标不会变回自动。 我喜欢这个解决方案,但我需要将事件绑定到 $(document),然后将类添加到 $('html) 以使其工作。【参考方案2】:

目前这两种浏览器都存在错误。两个链接上的更多详细信息(也在 cmets 中):

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

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

【讨论】:

2009 年报告的错误,但仍未得到证实。伤心。 感谢您的链接。第一个链接有一些有用的 cmets,包括 #87 (code.google.com/p/chromium/issues/detail?id=26723#c87),这是我现在使用的解决方法 对于现在遇到这个问题的人来说,虽然这个 bug 显然在 2013 年已经修复,但它有时在开发工具打开时仍然会发生(请参阅 2016 年 12 月关于 chromium bug 26723 的 cmets)。所以,像你的用户一样关闭开发工具,然后一切都很好:) @TimMalone 这是开发工具的具体问题。 bugs.chromium.org/p/chromium/issues/detail?id=676644 2017/08/20 chrome 60 中仍在发生,无论是否打开开发工具【参考方案3】:

我相信这个问题(包括 mousedown 问题)现在已在 Chrome 50 中得到修复。

但前提是你不使用开发者工具!!

关闭工具,光标应该会立即做出更好的反应。

【讨论】:

哈,没想到关闭开发者工具。谢谢! 关键是:关闭开发者工具! 在 chrome 60 中仍未修复 只是为了清楚,如果您重新加载页面,它不会修复,即 location.reload();真的很烦人......所以在完成后的ajax调用中执行location.reload();并且光标会出错。 在 63.0.3239.108(官方版本)(64 位)中也未修复 :(【参考方案4】:

我从 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 上移动光标(因此出现正常光标)。等待光标出现而不移动鼠标..

【讨论】:

并确保开发工具已关闭!【参考方案5】:

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

对于其他人说的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';

总之,您最好尝试在页面中添加静态微调器或其他显示加载过程的东西,而不是尝试使用光标来完成。

【讨论】:

【参考方案6】:

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 :(

【讨论】:

【参考方案7】:

Working solution on 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 上对我不起作用。光标一直保持等待光标,直到鼠标移动。 @PhilB 奇怪。它在 Windows 10 上的 Chrome 70.0.3538.77 上为我工作。我还成功地在包括 Windows 和 MacOS 在内的几十个环境中部署了这个解决方案,还没有这样的错误报告。 我使用的是 Windows 7,如果这会有所不同吗? :// @PhilB 可能会很好,因此可能有多种解决方案。我会留意这个 好的,我做了更多测试,似乎(正如其他提到的)我只能在打开开发工具的情况下重现该问题。我猜对我有好处。解决方案还可以。 :)【参考方案8】:

我认为你做不到。

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

【讨论】:

试过了。尝试了很多改动。它们都不足以对 Chrome 或 Safari 产生影响。好像很笨如果光标显示等待,用户为什么要触摸鼠标?【参考方案9】:

这是我的解决方案:

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


【讨论】:

【参考方案10】:

从 jquery 1.9 开始,你 should ajaxStart and ajaxStop to document。他们在 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' )  )

【讨论】:

【参考方案11】:

尝试为光标属性使用正确的 css 值:

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

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

【讨论】:

是的,对不起。那是一个错字。我正在使用(并且遇到问题)“等待”,而不是“忙碌”。【参考方案12】:

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

同样,我还没有对此进行测试,但值得一试。

【讨论】:

我尝试了很多时髦的东西,但浏览器似乎都忽略了它们。但如果我有时间,我会试试你的。 我也有同样的问题,全尺寸覆盖,并且光标在不移动时不会改变。【参考方案13】:

大家好,我有一个适用于所有浏览器的基本解决方案。假设使用原型库。也有人可以将其编写为纯 Javascript。解决方案是在您重置光标并稍微摇动它以使光标移动之后,在所有顶部放置一个 div。这发表在我的博客http://arunmobc.blogspot.com/2011/02/cursor-not-changing-issue.html。

【讨论】:

【参考方案14】:

$('*').css('cursor','wait');将在页面上的任何地方工作,包括链接

【讨论】:

将其应用于所有元素??不会发生。也没有修复错误。 这并不能解决问题。

以上是关于无需用户移动鼠标即可将浏览器光标从“等待”变为“自动”的主要内容,如果未能解决你的问题,请参考以下文章

无需在浏览器中登录即可将视频上传到 youtube

如何从用户代码中移动鼠标光标?

无需客户端浏览器即可将 HTML Canvas 保存为图像

无需激活即可将数据从 Access 导出到 Excel2013

无需卡即可将图像分享到 Twitter

无需重新下载即可将 TFS 工作区移动到另一台 PC