web-dev-qa-db-fra.com

Obtention du curseur de navigateur de "wait" à "auto" sans que l'utilisateur ne déplace la souris

J'utilise ce code jQuery pour définir le pointeur de la souris sur son état occupé (sablier) lors d'un appel Ajax ...

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

et ce code correspondant pour le remettre à la normale ...

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

Cela fonctionne bien ... sur certains navigateurs.

Sur Firefox et IE, dès que j'exécute la commande, le curseur de la souris change. C'est le comportement que je veux.

Sous Chrome et Safari, le curseur de la souris ne change pas de "occupé" à "auto" tant que l'utilisateur n'a pas déplacé le pointeur.

Quel est le meilleur moyen de faire basculer le pointeur de la souris avec les navigateurs réticents?

67
Nosredna

C'est un bug dans les deux navigateurs pour le moment. Plus de détails sur les deux liens (dans les commentaires également):

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

et 

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

34
user213788

Je préférerais le faire plus élégamment comme ceci:

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

38
Korayem

Je pense que ce problème (y compris le problème de la souris) est maintenant résolu dans Chrome 50. 

Mais seulement si vous n'utilisez pas les outils de développement!

Fermez les outils et le curseur devrait immédiatement mieux répondre.

20
J. Allen

Je me suis inspiré de la solution Korayem.

Javascript:

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

CSS:

.busy * {
    cursor: wait !important;
}

Testé sur Chrome, Firefox et IE 10. Le curseur change sans déplacer la souris. "! important" est nécessaire pour IE10.

Edit: Vous devez toujours déplacer le curseur sur IE 10 après que la demande AJAX est terminée (le curseur normal apparaît donc). Attendez que le curseur apparaisse sans déplacer la souris.

7
Sergiu

La solution de Korayem fonctionne pour moi à 100% dans Chrome moderne, Safari, à 95% dans Firefox, mais ne fonctionne pas dans Opera et IE.

Je l'ai amélioré un peu:

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

Maintenant, cela fonctionne à 100% dans Chrome, Safari, Firefox et Opera . Je ne sais pas quoi faire avec IE :(

1
Felix

Tout d'abord, sachez que si un curseur est attribué à une balise dans votre corps, $('body').css('cursor', 'wait'); ne changera pas le curseur de cette balise (comme moi, j'utilise cursor: pointer; sur toutes mes balises d'ancrage). Vous voudrez peut-être examiner d’abord ma solution à ce problème particulier: le curseur attend un appel ajax

Pour le problème que le curseur est mis à jour uniquement lorsque l'utilisateur déplace la souris sur les navigateurs Webkit, comme d'autres personnes l'ont dit, il n'y a pas de vraie solution.

Cela étant dit, il existe toujours une solution de contournement si vous ajoutez un css spinner au curseur actuel de manière dynamique. Ce n'est pas une solution parfaite parce que vous ne savez pas avec certitude la taille du curseur et si le compteur sera correctement positionné.

CSS spinner suivant le curseur: 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);

Vous devrez également vérifier s'il s'agit d'un périphérique tactile. var isTouchDevice = typeof window.ontouchstart !== 'undefined';

En conclusion, vous feriez mieux d’ajouter dans votre page un spinner statique ou autre chose qui montre le processus de chargement au lieu d’essayer de le faire avec le curseur.

1
pmrotule

Solution de travail sur CodeSandbox

Certaines des autres solutions ne fonctionnent pas dans toutes les circonstances. Nous pouvons atteindre le résultat souhaité avec deux règles CSS:

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

.not-busy {
  cursor: auto;
}

Le premier indique que nous sommes occupés et s’applique à tous les éléments de la page, en tentant de remplacer les autres styles de curseur. Ce dernier s'applique uniquement au corps de la page et est utilisé simplement pour forcer une mise à jour de l'interface utilisateur; nous voulons que cette règle soit aussi non spécifique que possible et qu'elle n'ait pas besoin de s'appliquer à d'autres éléments de page.

Nous pouvons alors déclencher et mettre fin à l'état occupé comme suit:

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

En résumé, bien que nous devions changer le style du curseur pour mettre à jour le curseur, la modification directe de document.body.style.cursor ou similaire n'a pas l'effet escompté, sur certains moteurs tels que Webkit, tant que le curseur n'est pas déplacé. L'utilisation de classes pour affecter le changement est plus robuste. Cependant, afin de forcer l'interface utilisateur à se mettre à jour (encore une fois, sur certains moteurs), nous devons ajouter une autre classe. Il semble que supprimer des classes soit traité différemment de les ajouter.

1
Ninjakannon

Je ne pense pas que vous serez capable de le faire.

Cependant, essayez de changer la position du défilement; cela pourrait aider.

0
SLaks

A partir de la version 1.9, vous devriez ajaxStart et ajaxStop pour documenter . Ils fonctionnent bien pour moi dans Firefox. Je n'ai pas testé dans d'autres navigateurs.

En CSS:

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

En javaScript:

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

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

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

}
0
cestar