Получить, если браузер занят - PullRequest
5 голосов
/ 20 ноября 2010

Я пытаюсь найти способ получить, если браузер в настоящее время занят из JavaScript.Я смотрю на создание расширения Firefox для вставки логического значения или чего-либо, если текущая страница загружает что-то (либо через ajax, либо просто при обычной загрузке страницы), либо то же самое с помощью скрипта Greasemonkey, либо через какой-то JavaScript API (этобыть лучшим решением, но из того, что я вижу, ничего подобного не существует).

Мне было интересно, как лучше всего это сделать.Я искал учебники Firefox Addon / Greasemonkey для создания чего-то подобного и не могу ничего найти.У кого-нибудь есть какие-либо советы или ресурсы, которые они могли бы указать мне на или лучшие решения для решения этой проблемы?

Спасибо

Изменить: и по занятости, я в основном просто должен знать, отправляет ли браузер илиполучение данных с сервера.

Ответы [ 3 ]

3 голосов
/ 21 ноября 2010

Вот то, что я думаю, я сделаю. Это решение похоже на то, которое Алекс предложил для событий Jquery, за исключением того, что оно работает со всем, что использует XMLHttpRequest (включая Jquery):

var runningAjaxCount = 0;

var oldSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {
    oldOnReady = this.onreadystatechange;
    this.onreadystatechange = function() {
        oldOnReady.call(this);
        if(this.readyState == XMLHttpRequest.DONE) {
            ajaxStopped();
        }
    }
    ajaxStarted();
    oldSend.apply(this, arguments);
}

function ajaxStarted() {
    runningAjaxCount++;
}

function ajaxStopped() {
    runningAjaxCount--;
}

function isCallingAjax() {
    return runningAjaxCount > 0;
}

function isBrowserBusy() {
    return document.readyState != "complete" && isCallingAjax();
}
3 голосов
/ 20 ноября 2010

jQuery , отличный javascript-фреймворк для манипулирования DOM и выполнения вызовов ajax, предоставляет две замечательные возможности для определения времени выполнения вызовов ajax:

$.ajaxStart() и $.ajaxStop()

Обе эти ловушки принимают функцию-обработчик, которая будет вызываться, когда собирается начать вызов ajax, и когда все вызовы ajax прекратились, соответственно.Эти функции могут быть связаны с любым элементом на странице.Вы можете установить глобальное логическое значение в вашем обработчике $.ajaxStart() на true и установить его обратно в false в вашем обработчике $.ajaxStop().

Затем вы можете проверить этот логический флаг и определить, выполняются ли вызовы AJAX.

Что-то вроде этого:

$(document).ajaxStart(function() {
    window.ajaxBusy = true;
});

$(document).ajaxStop(function() {
    window.ajaxBusy = false;
});

Что касается определения, когда браузер работаетзагружая текущую страницу, вы можете проверить document.readyState.Он возвращает строку "loading" во время загрузки документа и строку "complete" после загрузки.Вы можете привязать обработчик к document.onreadystatechange и установить глобальное логическое значение, которое будет указывать, загружается ли документ по-прежнему.

Примерно так:

document.onreadystatechange = function() {
    switch (document.readyState) {
        case "loading":
            window.documentLoading = true;
            break;
        case "complete":
            window.documentLoading = false;
            break;
        default:
            window.documentLoading = false;
    }
}   

РЕДАКТИРОВАТЬ:

Похоже, что $.ajaxStart() и $.ajaxStop() НЕ работают для вызовов ajax, вызываемых без jQuery.Все объекты XMLhttprequest имеют событие readystatechange, к которому вы можете прикрепить обработчик.Вы можете использовать эту функцию, чтобы определить, выполняется ли этот отдельный вызов.Вы можете поместить все ссылки на ожидающие вызовы в массив и проверить setInterval() длину этого массива.Если оно> 1, то существуют ajax-вызовы.Это грубый подход, и только один способ справиться с этим.Возможно, есть и другие способы сделать это.Но вот общий подход:

// declare array to hold references to outstanding requets
window.orequets = [];

var req = XMLHttpRequest(); 
// open the request and send it here....
// then attach a handler to `onreadystatechange`
req.onreadystatechange = function() {
    if (req.readyState != 4 || req.readyState != 3) {
        // req is still in progress
        orequests.push(req);
        window.reqPos = orequests.length -1
    } else {
        window.orequests = orequests.slice(reqPos, reqPos + 1);
    }
}

Выполните вышеуказанное для каждой XMLHttpRequest(), которую вы будете отправлять, конечно же, изменив имя запроса для каждого.Затем запустите setInterval(), который запускается каждые x миллисекунд, и проверяет свойство длины orequests.Если оно равно нулю, никаких запросов не происходит, если оно больше нуля, запросы все еще происходят.Если никаких запросов не происходит, вы можете либо очистить интервал через clearInterval(), либо оставить его включенным.

Ваш setInterval может выглядеть примерно так:

var ajaxInterval = setInterval(function() {
    if (orequests.length > 0) {
      // ajax calls are in progress
      window.xttpBusy = true;
    } else {
      // ajax calls have ceased
      window.xttpBusy = false;
      // you could call clearInterval(ajaxInterval) here but I don't know if that's your intention
    },
    3000 // run every 3 seconds. (You can decide how often you want to run it)
}); 
0 голосов
/ 20 ноября 2010

Технически браузер никогда не бывает "занят".Бизнес - это очень субъективный термин.Давайте предположим, что основной поток выполняет простой цикл while, который блокирует выполнение.Это может считаться занятым, но что, если у вас есть что-то вроде этого:

function busy() {setTimeout(busy, 0);do_something();}
busy();

Браузер не блокируется (сам по себе), поэтому вопрос о том, занята страница или нет, очень неясен.Кроме того, это даже не начинает затрагивать веб-работников и код в Chrome.

Вам будет сложно сделать это, и даже если вы это сделаете, скорее всего, это не сработаеткак вы ожидаете этого.Удачи, тем не менее.

...