Attendez le curseur sur toute la page html

89

Est-il possible de régler le curseur pour «attendre» sur toute la page html d'une manière simple? L'idée est de montrer à l'utilisateur que quelque chose se passe pendant qu'un appel ajax est terminé. Le code ci-dessous montre une version simplifiée de ce que j'ai essayé et démontre également les problèmes que je rencontre:

  1. si un élément (# id1) a un style de curseur défini, il ignorera celui défini sur le corps (évidemment)
  2. certains éléments ont un style de curseur par défaut (a) et n'afficheront pas le curseur d'attente au survol
  3. l'élément body a une certaine hauteur en fonction du contenu et si la page est courte, le curseur ne s'affichera pas sous le pied de page

Le test:

<html>
    <head>
        <style type="text/css">
            #id1 {
                background-color: #06f;
                cursor: pointer;
            }

            #id2 {
                background-color: #f60;
            }
        </style>
    </head>
    <body>
        <div id="id1">cursor: pointer</div>
        <div id="id2">no cursor</div>
        <a href="#" onclick="document.body.style.cursor = 'wait'; return false">Do something</a>
    </body>
</html>

Édition ultérieure ...
Cela a fonctionné dans Firefox et IE avec:

div#mask { display: none; cursor: wait; z-index: 9999; 
position: absolute; top: 0; left: 0; height: 100%; 
width: 100%; background-color: #fff; opacity: 0; filter: alpha(opacity = 0);}

<a href="#" onclick="document.getElementById('mask').style.display = 'block'; return false">
Do something</a>

Le problème avec (ou la caractéristique de) cette solution est qu'elle empêchera les clics en raison du chevauchement div (merci Kibbee)

Plus tard, modifier plus tard ...
Une solution plus simple de Dorward:

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

puis

<a href="#" onclick="document.body.className = 'wait'; return false">Do something</a>

Cette solution n'affiche que le curseur d'attente mais autorise les clics.

Aleris
la source
Comme il semble, je ne suis pas en mesure de changer le curseur pour les éléments sélectionnés. Existe-t-il également un moyen de modifier le curseur de l'élément de sélection?
Biswanath

Réponses:

34

Je comprends que vous n'avez peut-être pas le contrôle sur cela, mais vous pouvez plutôt opter pour un div "masquant" qui couvre tout le corps avec un z-index supérieur à 1. La partie centrale du div pourrait contenir un message de chargement si vous le souhaitez.

Ensuite, vous pouvez définir le curseur pour attendre sur le div et ne pas avoir à vous soucier des liens car ils sont "sous" votre div de masquage. Voici quelques exemples de CSS pour le "masking div":

corps {hauteur: 100%; }
div # mask {curseur: attendez; indice z: 999; hauteur: 100%; largeur: 100%; }
Eric Wendelin
la source
3
Cela peut souvent causer des problèmes. Dans Firefox, placer un div fixe sur toute la page fait que la page entière devient non cliquable. c'est-à-dire que vous ne pouvez pas cliquer sur les liens, parce que vous ne cliquez pas sur le lien que vous cliquez sur le div devant le lien.
Kibbee
1
Fonctionne bien dans Firefox. Pas de chance dans IE :(. Dans IE, il se comporte exactement comme si le div n'était pas là. Le seul moyen d'avoir le comportement souhaité est de définir une couleur sur le fond du div.
Aleris
2
Ok après un peu plus de lecture, il a finalement fonctionné avec: div # mask {display: none; curseur: attendez; indice z: 9999; position: absolue; haut: 0; gauche: 0; hauteur: 100%; largeur: 100%; couleur de fond: #fff; opacité: 0; filter: alpha (opacity = 0);}
Aleris
D'accord, Kibbee, cela dépend vraiment de votre comportement souhaité. On dirait qu'Aleris ne veut pas que l'utilisateur fasse quoi que ce soit (d'où le curseur d'attente) jusqu'à ce que AJAX rappelle.
Eric Wendelin
3
J'ai utilisé position: fixed donc il est toujours à l'écran, avec position: absolu ça ne s'afficherait pas quand j'étais en bas de page.
Jj.
111

Si vous utilisez cette version légèrement modifiée du CSS que vous avez posté de Dorward,

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

vous pouvez ensuite ajouter un jQuery très simple pour fonctionner pour tous les appels ajax:

$(document).ready(function () {
    $(document).ajaxStart(function () { $("html").addClass("wait"); });
    $(document).ajaxStop(function () { $("html").removeClass("wait"); });
});

ou, pour les anciennes versions de jQuery (avant la 1.9):

$(document).ready(function () {
    $("html").ajaxStart(function () { $(this).addClass("wait"); });
    $("html").ajaxStop(function () { $(this).removeClass("wait"); });
});
Dani
la source
4
Je veux vraiment utiliser cette réponse ... pourquoi n'est-elle pas acceptée?
gloomy.penguin
1
@ gloomy.penguin Cette question était active plus de 3 ans avant ma réponse, mais je suis tombée dessus dans ma propre recherche d'une solution, et j'ai décidé de partager la solution que j'ai fini par utiliser: un mélange de la réponse de Dorward, jQuery, et le bon sens de Kyle. C'est un peu différent de ce que recherchait l'OP, mais si cela fonctionne pour vous, utilisez-le! :)
Dani
Je suis d'accord. Fonctionne très bien et à mon humble avis, cela devrait être la réponse acceptée.
savehansson
1
Si cela ne fonctionne pas pour vous, vérifiez ici: JQuery.com "À partir de JQuery 1.9, les événements Ajax globaux ne sont déclenchés que sur l'élément de document." Ex:$(document).ajaxStart(function () { $("html").addClass("wait"); });
Debbie A
1
Avant de supprimer la classe d'attente, vous voudrez probablement vérifier si $.activeest 0, au cas où plusieurs demandes ont été faites et qu'elles ne sont pas encore terminées.
Shane Reustle
12

Cela semble fonctionner dans Firefox

<style>
*{ cursor: inherit;}
body{ cursor: wait;}
</style>

La partie * garantit que le curseur ne change pas lorsque vous survolez un lien. Bien que les liens soient toujours cliquables.

Kibbee
la source
* {curseur: attendez! important; } serait plus simple et plus susceptible de fonctionner dans IE (qui a beaucoup de bogues avec le mot-clé inherit)
Quentin
1
Est-ce que * {cursor: wait} peut être appliqué à partir de javascript? - sauf en itérant tous les éléments dans tout le DOM :)
Aleris
peut-être pourriez-vous ajouter un élément de style et définir le innerHTML. Ce ne serait pas très élégant, mais cela pourrait fonctionner.
Kibbee
3
.wait, .wait * {cusor: wait! important; } puis définissez document.body.className = 'wait'; avec JavaScript
Quentin
1
Notez qu'il y a une faute de frappe de "curseur" dans le commentaire ci-dessus, au cas où vous le copiez / collez.
devios1
7

Je lutte contre ce problème depuis des heures aujourd'hui. Fondamentalement, tout fonctionnait très bien dans FireFox mais (bien sûr) pas dans IE. Dans IE, le curseur d'attente était affiché APRÈS l'exécution de la fonction qui prend du temps.

J'ai enfin trouvé l'astuce sur ce site: http://www.codingforums.com/archive/index.php/t-37185.html

Code:

//...
document.body.style.cursor = 'wait';
setTimeout(this.SomeLongFunction, 1);

//setTimeout syntax when calling a function with parameters
//setTimeout(function() {MyClass.SomeLongFunction(someParam);}, 1);

//no () after function name this is a function ref not a function call
setTimeout(this.SetDefaultCursor, 1);
...

function SetDefaultCursor() {document.body.style.cursor = 'default';}

function SomeLongFunction(someParam) {...}

Mon code s'exécute dans une classe JavaScript d'où le this et MyClass (MyClass est un singleton).

J'ai eu les mêmes problèmes en essayant d'afficher un div comme décrit sur cette page. Dans IE, il était affiché après l'exécution de la fonction. Je suppose donc que cette astuce résoudrait également ce problème.

Merci mille fois à Glenngv l'auteur du message. Tu as vraiment fait ma journée !!!

pasx
la source
4

css: .waiting * { cursor: 'wait' }

jQuery: $('body').toggleClass('waiting');

redbmk
la source
2

Pourquoi n'utilisez-vous pas simplement l'un de ces graphiques de chargement sophistiqués (par exemple: http://ajaxload.info/ )? Le curseur en attente est pour le navigateur lui-même - donc chaque fois qu'il apparaît, il a quelque chose à voir avec le navigateur et non avec la page.

inexistante
la source
Je suis d'accord partiellement. Au moins sur les fenêtres, le curseur qui apparaît, si le navigateur lui-même charge une page, cursor: progressne l' est pas cursor: wait. L'utilisation de ce curseur serait beaucoup plus cohérente avec l'expérience utilisateur du navigateur. Mais j'aime vraiment l'idée de changer le curseur pour indiquer que le navigateur fonctionne comme il fonctionne lorsqu'il charge une page.
grippe
2

Le moyen le plus simple que je connaisse est d'utiliser JQuery comme ceci:

$('*').css('cursor','wait');
jere_hr
la source
cela pourrait prendre "une éternité" si vous avez beaucoup d'éléments, en particulier sur un ordinateur lent
redbmk
1

Essayez le css:

html.waiting {
cursor: wait;
}

Il semble que si la propriété bodyest utilisée comme apposée, htmlelle n'affiche pas le curseur d'attente sur toute la page. De plus, si vous utilisez une classe css, vous pouvez facilement contrôler quand elle l'affiche réellement.

Jeu habituel
la source
Quelle est cette classe d'attente? Est-ce quelque chose de personnalisé?
Sebas
1

Voici une solution plus élaborée qui ne nécessite pas de CSS externe:

function changeCursor(elem, cursor, decendents) {
    if (!elem) elem=$('body');

    // remove all classes starting with changeCursor-
    elem.removeClass (function (index, css) {
        return (css.match (/(^|\s)changeCursor-\S+/g) || []).join(' ');
    });

    if (!cursor) return;

    if (typeof decendents==='undefined' || decendents===null) decendents=true;

    let cname;

    if (decendents) {
        cname='changeCursor-Dec-'+cursor;
        if ($('style:contains("'+cname+'")').length < 1) $('<style>').text('.'+cname+' , .'+cname+' * { cursor: '+cursor+' !important; }').appendTo('head');
    } else {
        cname='changeCursor-'+cursor;
        if ($('style:contains("'+cname+'")').length < 1) $('<style>').text('.'+cname+' { cursor: '+cursor+' !important; }').appendTo('head');
    }

    elem.addClass(cname);
}

avec cela, vous pouvez faire:

changeCursor(, 'wait'); // wait cursor on all decendents of body
changeCursor($('#id'), 'wait', false); // wait cursor on elem with id only
changeCursor(); // remove changed cursor from body
kofifus
la source
1

J'ai utilisé une adaptation de la solution d' Eric Wendelin . Il affichera une superposition transparente et animée wait-div sur tout le corps, le clic sera bloqué par le wait-div lorsqu'il est visible:

css:

div#waitMask {
    z-index: 999;
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 100%;
    cursor: wait;
    background-color: #000;
    opacity: 0;
    transition-duration: 0.5s;
    -webkit-transition-duration: 0.5s;
}

js:

// to show it
$("#waitMask").show();
$("#waitMask").css("opacity"); // must read it first
$("#waitMask").css("opacity", "0.8");

...

// to hide it
$("#waitMask").css("opacity", "0");
setTimeout(function() {
    $("#waitMask").hide();
}, 500) // wait for animation to end

html:

<body>
    <div id="waitMask" style="display:none;">&nbsp;</div>
    ... rest of html ...
ungalcrys
la source
1

Mes deux pence:

Étape 1: Déclarez un tableau. Cela sera utilisé pour stocker les curseurs d'origine qui ont été affectés:

var vArrOriginalCursors = new Array(2);

Étape 2: implémenter la fonction cursorModifyEntirePage

 function CursorModifyEntirePage(CursorType){
    var elements = document.body.getElementsByTagName('*');
    alert("These are the elements found:" + elements.length);
    let lclCntr = 0;
    vArrOriginalCursors.length = elements.length; 
    for(lclCntr = 0; lclCntr < elements.length; lclCntr++){
        vArrOriginalCursors[lclCntr] = elements[lclCntr].style.cursor;
        elements[lclCntr].style.cursor = CursorType;
    }
}

Ce qu'il fait: Obtient tous les éléments de la page. Stocke les curseurs d'origine qui leur sont attribués dans le tableau déclaré à l'étape 1. Modifie les curseurs en curseur souhaité tel que passé par le paramètre CursorType

Étape 3: restaurer les curseurs de la page

 function CursorRestoreEntirePage(){
    let lclCntr = 0;
    var elements = document.body.getElementsByTagName('*');
    for(lclCntr = 0; lclCntr < elements.length; lclCntr++){
        elements[lclCntr].style.cursor = vArrOriginalCursors[lclCntr];
    }
}

J'ai exécuté ceci dans une application et cela fonctionne très bien. Le seul inconvénient est que je ne l'ai pas testé lorsque vous ajoutez dynamiquement les éléments.

indiaaditya
la source
1

Pour définir le curseur de JavaScript pour toute la fenêtre, utilisez:

document.documentElement.style.cursor = 'wait';

De CSS:

html { cursor: wait; }

Ajoutez une logique supplémentaire si nécessaire.

Peter J. de Bruin
la source
Cette solution javascript est la meilleure, fait le travail sans toucher au bagage HTML. C'est bien mieux que de basculer entre les classes sur des éléments, ce qui est très lent si vous avez beaucoup de nœuds dans votre DOM.
Rajshekar Reddy
0

Ce pur JavaScript semble fonctionner plutôt bien ... testé sur les navigateurs FireFox, Chrome et Edge.

Je ne suis pas sûr de la performance de cela si vous aviez une surabondance d'éléments sur votre page et un ordinateur lent ... essayez-le et voyez.

Définissez le curseur pour que tous les éléments attendent:

Object.values(document.querySelectorAll('*')).forEach(element => element.style.cursor = "wait");

Remettez le curseur de tous les éléments par défaut:

Object.values(document.querySelectorAll('*')).forEach(element => element.style.cursor = "default");

Une version alternative (et peut-être un peu plus lisible) serait de créer une fonction setCursor comme suit:

function setCursor(cursor)
{
    var x = document.querySelectorAll("*");

    for (var i = 0; i < x.length; i++)
    {
        x[i].style.cursor = cursor;
    }
}

puis appelez

setCursor("wait");

et

setCursor("default");

pour définir respectivement le curseur d'attente et le curseur par défaut.

javocity
la source