Attendi il cursore su tutta la pagina html


89

È possibile impostare il cursore per "attendere" sull'intera pagina html in modo semplice? L'idea è mostrare all'utente che sta succedendo qualcosa mentre una chiamata ajax viene completata. Il codice seguente mostra una versione semplificata di ciò che ho provato e mostra anche i problemi che incontro:

  1. se un elemento (# id1) ha uno stile del cursore impostato ignorerà quello impostato sul corpo (ovviamente)
  2. alcuni elementi hanno uno stile di cursore predefinito (a) e non mostreranno il cursore di attesa al passaggio del mouse
  3. l'elemento body ha una certa altezza a seconda del contenuto e se la pagina è corta, il cursore non verrà mostrato sotto il piè di pagina

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

Modifica successiva ...
Ha funzionato in Firefox e IE con:

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>

Il problema con (o caratteristica di) questa soluzione è che impedirà i clic a causa del div sovrapposto (grazie Kibbee)

Più tardi in seguito modifica ...
Una soluzione più semplice di Dorward:

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

e poi

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

Questa soluzione mostra solo il cursore di attesa ma consente i clic.


A quanto pare non sono in grado di cambiare il cursore per gli elementi selezionati. C'è un modo per cambiare il cursore anche per l'elemento selezionato?
Biswanath

Risposte:


34

Capisco che potresti non avere il controllo su questo, ma potresti invece optare per un div "mascherante" che copre l'intero corpo con uno z-index maggiore di 1. La parte centrale del div potrebbe contenere un messaggio di caricamento, se lo desideri.

Quindi, puoi impostare il cursore in modo che attenda sul div e non devi preoccuparti dei collegamenti poiché sono "sotto" il tuo div mascheramento. Ecco alcuni CSS di esempio per il "div mascheramento":

corpo {altezza: 100%; }
div # mask {cursore: aspetta; z-index: 999; altezza: 100%; larghezza: 100%; }

3
Ciò può spesso causare problemi. In Firefox, l'inserimento di un div fisso sull'intera pagina fa sì che l'intera pagina diventi non cliccabile. cioè, non puoi fare clic sui collegamenti, perché non stai facendo clic sul collegamento che stai facendo clic sul div davanti al collegamento.
Kibbee

1
Funziona bene in Firefox. Nessuna fortuna in IE :(. In IE si comporta esattamente come se il div non fosse presente. L'unico modo per avere il comportamento desiderato è impostare un colore sullo sfondo del div.
Aleris

2
Ok, dopo aver giocato ancora un po ', finalmente ha funzionato con: div # mask {display: none; cursore: aspetta; z-index: 9999; posizione: assoluta; in alto: 0; sinistra: 0; altezza: 100%; larghezza: 100%; colore di sfondo: #fff; opacità: 0; filtro: alfa (opacità = 0);}
Aleris

D'accordo, Kibbee, dipende davvero dal comportamento che desideri. Sembra che Aleris non voglia che l'utente faccia nulla (da qui il cursore di attesa) fino a quando AJAX non richiama.
Eric Wendelin

3
Ho usato position: fixed quindi è sempre sullo schermo, con position: absolute non sarebbe mostrato quando ero in fondo alla pagina.
Jj.

111

Se utilizzi questa versione leggermente modificata del CSS che hai pubblicato da Dorward,

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

puoi quindi aggiungere un po 'di jQuery davvero semplice per funzionare per tutte le chiamate ajax:

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

oppure, per le versioni precedenti di jQuery (precedenti alla 1.9):

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

4
Voglio davvero usare questa risposta ... perché non è quella accettata?
gloomy.penguin

1
@ gloomy.penguin Questa domanda era attiva più di 3 anni prima della mia risposta, ma mi sono imbattuto nella mia ricerca di una soluzione e ho deciso di condividere la soluzione che ho finito per usare: un misto della risposta di Dorward, jQuery, e il buon senso di Kyle. È un po 'diverso da quello che l'OP stava cercando, ma se funziona per te, allora usalo! :)
Dani

Sono d'accordo. Funziona alla grande e IMHO dovrebbe essere la risposta accettata.
savehansson

1
Se questo non funziona per te, controlla qui: JQuery.com "A partire da JQuery 1.9, gli eventi Ajax globali vengono attivati ​​solo sull'elemento del documento." Es:$(document).ajaxStart(function () { $("html").addClass("wait"); });
Debbie A

1
Prima di rimuovere la classe wait, probabilmente vorrai controllare se $.activeè 0, nel caso siano state fatte più richieste e non siano ancora finite.
Shane Reustle

12

Questo sembra funzionare in Firefox

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

La parte * assicura che il cursore non cambi quando passi il mouse su un collegamento. Sebbene i collegamenti saranno ancora cliccabili.


* {cursore: aspetta! importante; } sarebbe più semplice e più probabile che funzioni in IE (che ha molti bug con la parola chiave inherit)
Quentin

1
* {Cursor: wait} può essere applicato da javascript? - tranne che iterando tutti gli elementi nell'intero DOM :)
Aleris

forse potresti aggiungere un elemento di stile e impostare innerHTML. Non sarebbe molto elegante, ma potrebbe funzionare.
Kibbee,

3
.wait, .wait * {cusor: wait! important; } e quindi impostare document.body.className = 'wait'; con JavaScript
Quentin

1
Nota che c'è un errore di battitura di "cursore" nel commento sopra, nel caso in cui lo copi / incolli.
devios1

7

Ho lottato con questo problema per ore oggi. Fondamentalmente tutto funzionava bene in FireFox ma (ovviamente) non in IE. In IE il cursore di attesa veniva visualizzato DOPO l'esecuzione della funzione che richiede tempo.

Finalmente ho trovato il trucco su questo sito: http://www.codingforums.com/archive/index.php/t-37185.html

Codice:

//...
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) {...}

Il mio codice viene eseguito in una classe JavaScript, quindi questa e MyClass (MyClass è un singleton).

Ho avuto gli stessi problemi durante il tentativo di visualizzare un div come descritto in questa pagina. In IE veniva visualizzato dopo che la funzione era stata eseguita. Quindi immagino che questo trucco risolverebbe anche quel problema.

Grazie mille a glenngv l'autore del post. Mi hai davvero reso la giornata !!!


4

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

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


2

Perché non usi solo uno di quei fantasiosi grafici di caricamento (ad esempio: http://ajaxload.info/ )? Il cursore in attesa è per il browser stesso, quindi ogni volta che appare ha qualcosa a che fare con il browser e non con la pagina.


Sono d'accordo parzialmente. Almeno su Windows il cursore che appare, se il browser stesso sta caricando una pagina, cursor: progressnon lo è cursor: wait. L'utilizzo di quel cursore sarebbe molto più coerente con l'esperienza utente del browser. Ma mi piace molto l'idea di cambiare il cursore per indicare che il browser funziona proprio come funziona quando carica una pagina.
influenza il

2

Il modo più semplice che conosco è usare JQuery in questo modo:

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

potrebbe volerci "per sempre" se hai molti elementi, specialmente su un computer lento
redbmk

1

Prova il css:

html.waiting {
cursor: wait;
}

Sembra che se la proprietà bodyviene utilizzata come apposta htmlnon mostra il cursore di attesa su tutta la pagina. Inoltre se usi una classe CSS puoi facilmente controllare quando la mostra effettivamente.


Cos'è quella lezione d'attesa? È qualcosa di personalizzato?
Sebas

1

Ecco una soluzione più elaborata che non richiede CSS esterni:

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

con questo puoi fare:

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

1

Ho usato un adattamento della soluzione di Eric Wendelin . Mostrerà un wait-div trasparente e animato su tutto il corpo, il clic sarà bloccato dal wait-div mentre è visibile:

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

1

I miei due pence:

Passaggio 1: dichiara un array. Questo verrà utilizzato per memorizzare i cursori originali assegnati:

var vArrOriginalCursors = new Array(2);

Passaggio 2: implementare la funzione 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;
    }
}

Che cosa fa: ottiene tutti gli elementi sulla pagina. Memorizza i cursori originali ad essi assegnati nell'array dichiarato nel passaggio 1. Modifica i cursori al cursore desiderato come passato dal parametro CursorType

Passaggio 3: ripristinare i cursori sulla pagina

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

L'ho eseguito in un'applicazione e funziona bene. L'unico avvertimento è che non l'ho testato quando si aggiungono dinamicamente gli elementi.


1

Per impostare il cursore da JavaScript per l'intera finestra, utilizzare:

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

Da CSS:

html { cursor: wait; }

Aggiungi ulteriore logica se necessario.


Questa soluzione javascript è la migliore, fa il lavoro senza toccare il bagaglio HTML. Questo è molto meglio che alternare classi su elementi che è molto lento se hai molti nodi nel tuo DOM.
Rajshekar Reddy


0

Questo JavaScript puro sembra funzionare abbastanza bene ... testato su FireFox, Chrome e browser Edge.

Non sono sicuro delle prestazioni di questo se avessi una sovrabbondanza di elementi sulla tua pagina e un computer lento ... provalo e guarda.

Imposta il cursore per far aspettare tutti gli elementi:

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

Imposta il cursore per tutti gli elementi sul valore predefinito:

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

Una versione alternativa (e forse un po 'più leggibile) sarebbe quella di creare una funzione setCursor come segue:

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

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

e poi chiama

setCursor("wait");

e

setCursor("default");

per impostare rispettivamente il cursore di attesa e il cursore predefinito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.