Зачекайте курсор на всю HTML-сторінку


89

Чи можна просто встановити курсор на "очікування" на всій сторінці html? Ідея полягає в тому, щоб показати користувачеві, що щось відбувається, поки завершується виклик ajax. У наведеному нижче коді показано спрощену версію того, що я спробував, а також продемонстровано проблеми, з якими я стикаюся:

  1. якщо для елемента (# id1) встановлено стиль курсору, він буде ігнорувати той, що встановлений на тілі (очевидно)
  2. деякі елементи мають стиль курсору за замовчуванням (a) і не відображатимуть курсор очікування при наведенні
  3. елемент body має певну висоту в залежності від вмісту, і якщо сторінка коротка, курсор не відображатиметься під колонтитулом

Тест:

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

Пізніше редагувати ...
Це працювало у Firefox та IE з:

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>

Проблема (або особливість) цього рішення полягає в тому, що воно запобіжить клацанню через перекриття div (спасибі Kibbee)

Пізніше редагуйте ...
Більш просте рішення від Dorward:

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

і потім

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

Це рішення відображає лише курсор очікування, але дозволяє клацати.


Як видається, я не можу змінити курсор для вибраних елементів. Чи є спосіб змінити курсор для елемента select також?
Бісванат,

Відповіді:


33

Я розумію, ви, можливо, не маєте над цим контролю, але замість цього ви можете вибрати "маскуючий" div, який охоплює все тіло з z-індексом вище 1. Центральна частина div може містити повідомлення про завантаження, якщо хочете.

Потім ви можете встановити курсор, щоб він чекав на div, і вам не доведеться турбуватися про посилання, оскільки вони знаходяться "під" вашим маскуючим div. Ось декілька прикладів CSS для "маскування div":

тіло {зріст: 100%; }
div # mask {курсор: чекати; z-індекс: 999; висота: 100%; ширина: 100%; }

3
Це часто може спричинити проблеми. У Firefox розміщення фіксованого div на всій сторінці призводить до того, що всю сторінку стає неможливо натиснути. тобто ви не можете натискати на посилання, оскільки ви не натискаєте на посилання, а натискаєте на div перед посиланням.
Кібі

1
Працює нормально у Firefox. Не пощастило в IE :(. В IE він поводиться точно так, ніби div там немає. Єдиний спосіб отримати бажану поведінку - це встановити колір на тлі div.
Aleris,

2
Гаразд, ще трохи погравши, нарешті вдалося: div # mask {display: none; курсор: чекати; z-індекс: 9999; позиція: абсолютна; зверху: 0; ліворуч: 0; висота: 100%; ширина: 100%; фон-колір: #fff; непрозорість: 0; фільтр: альфа (непрозорість = 0);}
Алеріс,

Згоден, Кібі, це справді залежить від вашої бажаної поведінки. Схоже, Алеріс не хоче, щоб користувач нічого не робив (отже, курсор очікування), поки AJAX не передзвонить.
Ерік Венделін,

3
Я використовував position: fixed, тому він завжди на екрані, з position: absolute він не відображався б, коли я знаходився внизу сторінки.
Jj.

111

Якщо ви використовуєте цю трохи змінену версію CSS, яку ви опублікували від Dorward,

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

потім ви можете додати справді простий jQuery для роботи з усіма викликами ajax:

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

або для старих версій jQuery (до 1.9):

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

4
Я дуже хочу використати цю відповідь ... чому вона не прийнята?
gloomy.penguin

1
@ gloomy.penguin Це питання було активним понад 3 роки до моєї відповіді, але я трапився з ним під час власного пошуку рішення і вирішив поділитися рішенням, яке в підсумку використав: суміш відповіді Дорварда, jQuery, і здоровий глузд Кайла. Це трохи відрізняється від того, що шукав ОП, але якщо він працює для вас, то скористайтеся ним! :)
Дані

Я згоден. Чудово працює, і IMHO це має бути прийнятою відповіддю.
Савегансон

1
Якщо це не працює для вас, перевірте тут: JQuery.com "Починаючи з JQuery 1.9, глобальні події Ajax запускаються лише для елемента документа." Приклад:$(document).ajaxStart(function () { $("html").addClass("wait"); });
Деббі А,

1
Перш ніж видалити клас очікування, ви, мабуть, хочете перевірити, чи $.activeдорівнює 0, якщо було зроблено кілька запитів, і вони ще не завершені.
Шейн Рестл

12

Здається, це працює у firefox

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

Частина * гарантує, що курсор не зміниться, коли ви наведете курсор на посилання. Хоча посилання все одно можна буде натиснути.


* {курсор: чекай! важливо; } було б простіше і з більшою ймовірністю працювало б в IE (у якій багато помилок із ключовим словом спадкування)
Квентін

1
Чи можна застосувати * {курсор: чекати} з JavaScript? - за винятком повторення всіх елементів у цілому DOM :)
Алеріс,

можливо, ви можете додати елемент стилю та встановити innerHTML. Це було б не дуже елегантно, але це може спрацювати.
Кібі

3
.чекай, .чекай * {cusor: wait! important; }, а потім встановіть document.body.className = 'зачекати'; з JavaScript
Квентін,

1
Зверніть увагу, що у наведеному вище коментарі є помилка "курсор" на випадок, якщо ви скопіюєте / вставите його.
devios1

7

Сьогодні я борюся з цією проблемою годинами. В основному все працювало добре у FireFox, але (звичайно) не в IE. В IE курсор очікування відображався ПІСЛЯ виконання тривалої функції.

Нарешті я знайшов фокус на цьому веб-сайті: http://www.codingforums.com/archive/index.php/t-37185.html

Код:

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

Мій код працює в класі JavaScript, отже це і MyClass (MyClass є одностороннім).

У мене були ті самі проблеми при спробі відобразити div, як описано на цій сторінці. В IE це відображалося після виконання функції. Тож я думаю, цей трюк також вирішить цю проблему.

Дякую мільйон часу glenngv автору допису. Ви справді встигли мені день !!!



2

Чому б вам просто не використати одну з цих вигадливих графік завантаження (наприклад: http://ajaxload.info/ )? Курсор очікування стосується самого браузера - тому, коли він з’являється, він має щось спільне з браузером, а не зі сторінкою.


Я частково погоджуюсь. Принаймні у вікнах курсор, який з'являється, якщо браузер сам завантажує сторінку, - cursor: progressні cursor: wait. Використання цього курсору було б набагато більш узгодженим із користувацьким досвідом роботи браузера. Але мені дуже подобається ідея зміни курсору, щоб вказати, що браузер працює так само, як і при завантаженні сторінки.
грип

2

Найпростіший спосіб, який я знаю, - використовувати JQuery таким чином:

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

це може зайняти "вічно", якщо у вас багато елементів, особливо на повільному комп'ютері
redbmk

1

Спробуйте css:

html.waiting {
cursor: wait;
}

Здається, якщо властивість bodyвикористовується за призначенням, htmlвона не відображає курсор очікування на всій сторінці. Крім того, якщо ви використовуєте клас css, ви можете легко контролювати, коли він насправді його показує.


Що це за клас очікування? Це щось на замовлення?
Себас,

1

Ось більш складне рішення, яке не вимагає зовнішнього 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);
}

за допомогою цього ви можете зробити:

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

Я використав екранізацію Еріка Венделіна . Він покаже прозоре, анімоване накладання очікування-div по всьому тілу, клацання буде заблоковано методом очікування-div, поки буде видимим:

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

Мої два пенси:

Крок 1: Оголосіть масив. Це буде використано для зберігання оригінальних курсорів, яким було призначено:

var vArrOriginalCursors = new Array(2);

Крок 2: Реалізуйте функцію 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;
    }
}

Що робить: Отримує всі елементи на сторінці. Зберігає оригінальні курсори, призначені їм у масиві, оголошеному на кроці 1. Змінює курсори до потрібного курсору, переданого параметром CursorType

Крок 3: Відновіть курсори на сторінці

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

Я запустив це в додатку, і воно працює нормально. Єдине застереження полягає в тому, що я не тестував його, коли ви динамічно додаєте елементи.


1

Щоб встановити курсор з JavaScript для всього вікна, використовуйте:

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

З CSS:

html { cursor: wait; }

За потреби додайте додаткову логіку.


Це рішення javascript найкраще, виконує роботу, не торкаючись багажу HTML. Це набагато краще, ніж перемикання класів на елементи, що відбувається дуже повільно, якщо у вас є багато вузлів у вашому DOM.
Раджшекар Редді


0

Здається, цей чистий JavaScript працює досить добре ... протестований на браузерах FireFox, Chrome та Edge.

Я не впевнений у роботі цього, якщо на вашій сторінці було занадто багато елементів і повільний комп'ютер ... спробуйте і подивіться.

Встановіть курсор для всіх елементів, які очікують:

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

Встановити курсор для всіх елементів за замовчуванням:

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

Альтернативною (і, можливо, трохи читабельнішою) версією буде створення функції setCursor наступним чином:

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

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

а потім зателефонувати

setCursor("wait");

і

setCursor("default");

щоб встановити курсор очікування та курсор за замовчуванням відповідно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.