Подождите, пока курсор переместится на всю 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)

Позже позже отредактируйте ...
Более простое решение от Дорварда:

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

а потом

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

Это решение показывает только курсор ожидания, но разрешает щелчки.

Aleris
источник
Кажется, я не могу изменить курсор для выбранных элементов. Есть ли способ также изменить курсор для элемента выбора?
Бисванат

Ответы:

34

Я понимаю, что у вас может не быть контроля над этим, но вместо этого вы можете использовать «маскирующий» div, который покрывает все тело с z-index выше 1. Центральная часть div может содержать сообщение о загрузке, если хотите.

Затем вы можете установить курсор так, чтобы он ждал на div и не беспокоиться о ссылках, поскольку они находятся «под» вашим маскирующим div. Вот пример CSS для «маскирующего div»:

body {высота: 100%; }
div # маска {курсор: ждать; z-индекс: 999; высота: 100%; ширина: 100%; }
Эрик Венделин
источник
3
Это часто может вызвать проблемы. В Firefox размещение фиксированного блока div на всей странице приводит к тому, что вся страница становится неактивной. т.е. вы не можете нажимать ссылки, потому что вы не нажимаете на ссылку, которую вы нажимаете на div перед ссылкой.
Kibbee
1
Работает нормально в firefox. Не повезло в IE :(. В IE он ведет себя точно так же, как если бы div там нет. Единственный способ добиться желаемого поведения - установить цвет на фоне div.
Aleris
2
Хорошо, немного поиграв, он наконец заработал: div # mask {display: none; курсор: ждать; z-индекс: 9999; позиция: абсолютная; верх: 0; слева: 0; высота: 100%; ширина: 100%; цвет фона: #fff; непрозрачность: 0; filter: alpha (opacity = 0);}
Aleris,
Согласен, Кибби, это действительно зависит от твоего желаемого поведения. Похоже, что Aleris не хочет, чтобы пользователь что-либо делал (отсюда и курсор ожидания), пока 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, и здравый смысл Кайла. Это немного отличается от того, что искал OP, но если он работает для вас, используйте его! :)
Дэни
Согласен. Отлично работает, и IMHO это должен быть принятый ответ.
savehansson
1
Если это не работает для вас, проверьте здесь: JQuery.com «Начиная с JQuery 1.9, глобальные события Ajax запускаются только для элемента документа». Пример:$(document).ajaxStart(function () { $("html").addClass("wait"); });
Debbie A
1
Перед удалением класса ожидания вы, вероятно, захотите проверить, $.activeравен ли 0, если было сделано несколько запросов, и все они еще не завершены.
Шейн Рустл
12

Кажется, это работает в firefox

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

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

Кибби
источник
* {курсор: подождите! важно; } будет проще и с большей вероятностью будет работать в IE (в котором много ошибок с ключевым словом inherit)
Квентин,
1
Можно ли применить * {cursor: wait} из javascript? - за исключением итерации всех элементов во всем DOM :)
Aleris
возможно, вы могли бы добавить элемент стиля и установить innerHTML. Было бы не очень элегантно, но могло бы сработать.
Кибби
3
.wait, .wait * {cusor: wait! important; } и затем установите document.body.className = 'wait'; с 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, следовательно, this и MyClass (MyClass - одноэлементный).

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

Огромное спасибо glenngv автору сообщения. Ты действительно сделал мой день !!!

pasx
источник
4

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

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

Redbmk
источник
2

Почему бы вам просто не использовать одну из этих причудливых графиков загрузки (например: http://ajaxload.info/ )? Курсор ожидания предназначен для самого браузера, поэтому всякий раз, когда он появляется, он имеет какое-то отношение к браузеру, а не к странице.

несуществующий
источник
Частично согласен. По крайней мере, в окнах курсор, который появляется, если браузер сам загружает страницу, cursor: progressнет cursor: wait. Использование этого курсора будет намного более согласованным с пользовательским интерфейсом браузера. Но мне очень нравится идея изменения курсора, чтобы указать, что браузер работает так же, как он работает при загрузке страницы.
грипп
2

Самый простой способ, который я знаю, - использовать JQuery следующим образом:

$('*').css('cursor','wait');
jere_hr
источник
это может занять «вечность», если у вас много элементов, особенно на медленном компьютере
redbmk
1

Попробуйте css:

html.waiting {
cursor: wait;
}

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

GameFreak
источник
Что это за класс ожидания? Это что-то нестандартное?
Себас
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

Я использовал адаптацию решения Эрика Венделина . Он покажет прозрачный, анимированный оверлей wait-div по всему телу, щелчок будет заблокирован wait-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");

для установки курсора ожидания и курсора по умолчанию соответственно.

веселость
источник