Poczekaj na kursor na całej stronie html


89

Czy można w prosty sposób ustawić kursor na „czekaj” na całej stronie html? Chodzi o to, aby pokazać użytkownikowi, że coś się dzieje podczas kończenia połączenia AJAX. Poniższy kod pokazuje uproszczoną wersję tego, co wypróbowałem, a także pokazuje problemy, na które napotykam:

  1. jeśli element (# id1) ma ustawiony styl kursora, zignoruje ten ustawiony na body (oczywiście)
  2. niektóre elementy mają domyślny styl kursora (a) i nie będą wyświetlać kursora oczekiwania po najechaniu
  3. element body ma określoną wysokość w zależności od zawartości i jeśli strona jest krótka, kursor nie pojawi się pod stopką

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>

Później edycja ...
Działało w Firefox i IE z:

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>

Problem z tym rozwiązaniem (lub jego cechą) polega na tym, że zapobiegnie ono kliknięciom z powodu nakładającego się elementu div (dzięki Kibbee)

Później później edytuj ...
Prostsze rozwiązanie od Dorward:

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

i wtedy

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

To rozwiązanie pokazuje tylko kursor oczekiwania, ale umożliwia kliknięcia.


Jak się wydaje, nie jestem w stanie zmienić kursora dla wybranych elementów. Czy istnieje również sposób zmiany kursora dla wybranego elementu?
Biswanath,

Odpowiedzi:


34

Rozumiem, że możesz nie mieć nad tym kontroli, ale możesz zamiast tego wybrać element div „maskujący”, który obejmuje całą treść z indeksem z wyższym niż 1. Środkowa część elementu div może zawierać komunikat o ładowaniu, jeśli chcesz.

Następnie możesz ustawić kursor tak, aby czekał na element div i nie musisz martwić się o linki, ponieważ znajdują się one „pod” Twoim elementem div maskującym. Oto przykład CSS dla „elementu div maskującego”:

body {wysokość: 100%; }
div # mask {kursor: czekaj; indeks z: 999; wysokość: 100%; szerokość: 100%; }

3
Może to często powodować problemy. W przeglądarce Firefox umieszczenie stałego elementu div na całej stronie powoduje, że cała strona staje się niemożliwa do kliknięcia. tj. nie możesz klikać łączy, ponieważ nie klikasz linku, ale klikasz element div przed łączem.
Kibbee

1
Działa dobrze w przeglądarce Firefox. Brak powodzenia w IE :(. W IE zachowuje się dokładnie tak, jakby nie było elementu div. Jedynym sposobem uzyskania pożądanego zachowania jest ustawienie koloru tła div.
Aleris

2
Ok, po dłuższym graniu w końcu zadziałało: div # mask {display: none; kursor: czekaj; indeks z: 9999; pozycja: bezwzględna; góra: 0; po lewej: 0; wysokość: 100%; szerokość: 100%; background-color: #fff; krycie: 0; filter: alpha (opacity = 0);}
Aleris

Zgoda, Kibbee, to naprawdę zależy od twojego pożądanego zachowania. Wygląda na to, że Aleris nie chce, aby użytkownik nic robił (stąd kursor oczekiwania), dopóki AJAX nie oddzwoni.
Eric Wendelin

3
Użyłem position: ustalone, więc zawsze jest na ekranie, z position: bezwzględne, nie wyświetlało się, gdy byłem na dole strony.
Jj.

111

Jeśli używasz tej nieco zmodyfikowanej wersji CSS, którą opublikowałeś od Dorward,

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

możesz wtedy dodać naprawdę proste jQuery do pracy dla wszystkich wywołań ajax:

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

lub dla starszych wersji jQuery (przed 1.9):

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

4
Naprawdę chcę użyć tej odpowiedzi ... dlaczego nie jest ona zaakceptowana?
ponury.pingwin

1
@ gloomy.penguin To pytanie było aktywne ponad 3 lata przed moją odpowiedzią, ale natknąłem się na nie w moich własnych poszukiwaniach rozwiązania i postanowiłem podzielić się rozwiązaniem, z którego ostatecznie skorzystałem: mieszanką odpowiedzi Dorwarda, jQuery, i rozsądek Kyle'a. To trochę różni się od tego, czego szukał OP, ale jeśli to działa, użyj go! :)
Dani

Zgadzam się. Działa świetnie i IMHO powinna to być akceptowana odpowiedź.
savehansson,

1
Jeśli to nie działa, sprawdź tutaj: JQuery.com „Od wersji JQuery 1.9 globalne zdarzenia Ajax są wyzwalane tylko w elemencie dokumentu”. Np .:$(document).ajaxStart(function () { $("html").addClass("wait"); });
Debbie A,

1
Przed usunięciem klasy wait prawdopodobnie zechcesz sprawdzić, czy $.activewynosi 0, w przypadku, gdy wykonano wiele żądań i wszystkie nie są jeszcze zakończone.
Shane Reustle

12

Wydaje się, że to działa w przeglądarce Firefox

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

Część * zapewnia, że ​​kursor nie zmienia się po najechaniu kursorem na łącze. Chociaż linki nadal będą klikalne.


* {kursor: czekaj! ważne; } byłby prostszy i bardziej prawdopodobny do działania w IE (który ma wiele błędów związanych ze słowem kluczowym inherit)
Quentin

1
Czy * {kursor: czekaj} można zastosować z javascript? - z wyjątkiem iteracji wszystkich elementów w całym DOM :)
Aleris

może mógłbyś dodać element style i ustawić innerHTML. Nie byłoby zbyt eleganckie, ale mogłoby się udać.
Kibbee

3
.wait, .wait * {cusor: czekaj! ważne; }, a następnie ustaw document.body.className = 'czekaj'; z JavaScript
Quentin,

1
Zauważ, że w powyższym komentarzu znajduje się literówka „kursor”, na wypadek gdybyś go skopiował / wkleił.
devios1

7

Walczę z tym problemem od wielu godzin. W zasadzie wszystko działało dobrze w FireFox, ale (oczywiście) nie w IE. W IE kursor oczekiwania pokazywał się PO wykonaniu czasochłonnej funkcji.

W końcu znalazłem sztuczkę na tej stronie: http://www.codingforums.com/archive/index.php/t-37185.html

Kod:

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

Mój kod działa w klasie JavaScript, stąd this i MyClass (MyClass to singleton).

Miałem te same problemy, gdy próbowałem wyświetlić element div, jak opisano na tej stronie. W IE pokazywał się po wykonaniu funkcji. Więc myślę, że ta sztuczka rozwiązałaby również ten problem.

Dzięki zillion czasu glenngv autorowi posta. Naprawdę sprawiłeś, że mój dzień !!!


4

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

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


2

Dlaczego po prostu nie użyjesz jednej z tych wymyślnych grafik do ładowania (np .: http://ajaxload.info/ )? Kursor oczekiwania jest przeznaczony dla samej przeglądarki - więc gdy się pojawi, ma coś wspólnego z przeglądarką, a nie ze stroną.


Zgadzam się częściowo. Przynajmniej w oknach kursor, który się pojawia, jeśli przeglądarka sama ładuje stronę, cursor: progressnie cursor: wait. Korzystanie z tego kursora byłoby znacznie bardziej spójne z doświadczeniem użytkownika przeglądarki. Ale bardzo podoba mi się pomysł zmiany kursora, aby wskazać, że przeglądarka działa tak, jak działa, gdy ładuje stronę.
grypa

2

Najłatwiejszy sposób, jaki znam, to używanie JQuery w następujący sposób:

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

to może zająć „wieczność”, jeśli masz dużo elementów, zwłaszcza na wolnym komputerze
redbmk

1

Wypróbuj CSS:

html.waiting {
cursor: wait;
}

Wygląda na to, że jeśli właściwość bodyjest używana jako dołączona do htmlniej, kursor oczekiwania na całej stronie nie jest wyświetlany. Ponadto, jeśli używasz klasy css, możesz łatwo kontrolować, kiedy faktycznie ją wyświetla.


Co to za klasa czekania? Czy to coś niestandardowego?
Sebas

1

Oto bardziej rozbudowane rozwiązanie, które nie wymaga zewnętrznego CSS:

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

dzięki temu możesz:

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

Użyłem adaptacji rozwiązania Erica Wendelina . Wyświetli przezroczystą, animowaną nakładkę elementu div na całe ciało, kliknięcie zostanie zablokowane przez element div wait, gdy będzie widoczny:

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

Moje dwa pensy:

Krok 1: Zadeklaruj tablicę. Będzie to używane do przechowywania oryginalnych kursorów, które zostały przypisane:

var vArrOriginalCursors = new Array(2);

Krok 2: Zaimplementuj funkcję 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;
    }
}

Co robi: Pobiera wszystkie elementy na stronie. Przechowuje oryginalne kursory przypisane do nich w tablicy zadeklarowanej w kroku 1. Modyfikuje kursory na żądany kursor przekazany przez parametr CursorType

Krok 3: Przywróć kursory na stronie

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

Uruchomiłem to w aplikacji i działa dobrze. Jedynym zastrzeżeniem jest to, że nie testowałem go, gdy dynamicznie dodajesz elementy.


1

Aby ustawić kursor z JavaScript dla całego okna, użyj:

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

Z CSS:

html { cursor: wait; }

W razie potrzeby dodaj dalszą logikę.


To rozwiązanie javascript jest najlepsze, działa bez dotykania bagażu HTML. Jest to o wiele lepsze niż przełączanie klas na elementach, co jest bardzo powolne, jeśli masz dużo węzłów w swoim DOM.
Rajshekar Reddy


0

Ten czysty JavaScript wydaje się działać całkiem nieźle ... przetestowany w przeglądarkach FireFox, Chrome i Edge.

Nie jestem pewien co do wydajności, gdybyś miał nadmiar elementów na swojej stronie i wolny komputer ... spróbuj i zobacz.

Ustaw kursor na czekanie wszystkich elementów:

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

Ustaw kursor dla wszystkich elementów z powrotem na domyślne:

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

Alternatywną (i być może nieco bardziej czytelną) wersją byłoby utworzenie funkcji setCursor w następujący sposób:

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

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

a następnie zadzwoń

setCursor("wait");

i

setCursor("default");

aby ustawić odpowiednio kursor oczekiwania i kursor domyślny.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.