2010-11-20 18 views
5

Próbuję znaleźć sposób, aby uzyskać dostęp, jeśli przeglądarka jest obecnie zajęta z JavaScript. Szukam rozszerzenia Firefox do wstrzyknięcia wartości Boolean lub coś, jeśli bieżąca strona ładuje coś (albo przez ajax lub po prostu normalne ładowanie strony), lub to samo ze skryptem Greasemonkey, lub za pomocą niektórych JavaScript API (to by być najlepszym rozwiązaniem, ale z tego, co widzę, nic takiego nie istnieje).Sprawdź, czy przeglądarka jest zajęta

Zastanawiam się, jaki byłby najlepszy sposób na zrobienie tego. Szukałem samouczków do Firefoksa Addon/Greasemonkey do robienia czegoś takiego i nie mogę znaleźć niczego. Czy ktoś ma jakieś wskazówki lub zasoby, które mogą wskazać mi lub lepsze rozwiązania tego rozwiązania?

Dzięki

EDIT: i przez zajęty, ja przeważnie wystarczy wiedzieć, czy przeglądarka wysyła lub odbiera dane z serwera.

Odpowiedz

2

Oto, co myślę, że skończę. To rozwiązanie jest jak jeden Alex zaproponował z wydarzeniami jQuery, z wyjątkiem, że to działa z czymkolwiek, który używa XMLHttpRequest (łącznie z 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(); 
} 
+0

Pomyślałem, że skomentuję i powiem, że 3 lata później wciąż używamy tego podstawowego podejścia i działa świetnie! – Joel

+0

To jest naprawdę niesamowite! Dzięki! Naprawdę przydatny do automatycznego testowania/skrobania witryn. – Evers

4

jQuery, wielki ramach JavaScript manipulacji DOM i wykonywania połączeń Ajax oferuje dwie wielkie haki do określania, kiedy połączenia Ajax są w toku:

$.ajaxStart() i $.ajaxStop()

Oba haki podjęcia funkcji obsługi który zostanie wywołany, gdy rozpocznie się połączenie ajaxowe, a kiedy wszystkie wywołania ajaxowe zostaną przerwane, odpowiednio. Te funkcje można powiązać z dowolnym elementem na stronie. Możesz ustawić globalną wartość logiczną w twoim sterowniku $.ajaxStart() na wartość true i ustawić ją z powrotem na false w twojej procedurze obsługi $.ajaxStop().

Następnie można sprawdzić flagę binarną i określić, czy wywołania ajax są w toku.

Coś wzdłuż tych linii:

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

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

miarę ustalania gdy przeglądarka jest ładowanie bieżącej strony, można sprawdzić document.readyState. Zwraca ciąg "loading" podczas ładowania dokumentu i ciąg "complete" po załadowaniu. Można powiązać program obsługi z document.onreadystatechange i ustawić globalną wartość logiczną, która będzie wskazywała, czy dokument wciąż się ładuje, czy nie.

coś takiego:

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

EDIT:

Wydaje się, że $.ajaxStart() i $.ajaxStop() nie działa dla wywołań ajax wywołany bez jQuery. Wszystkie obiekty XMLhttprequest mają wydarzenie o nazwie readystatechange, do którego można dołączyć moduł obsługi. Możesz wykorzystać tę funkcję, aby ustalić, czy to indywidualne połączenie zostało wykonane. Możesz przesłać wszystkie odwołania do zaległych połączeń do tablicy, a następnie w polu setInterval() sprawdzić długość tablicy. Jeśli to> 1, nie są już stojące wywołania ajax. Jest to podejście surowe i tylko jeden sposób na uzyskanie tego. Są prawdopodobnie inne sposoby na zrobienie tego. Ale tu ogólne podejście:

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

Czy powyższe dla każdego XMLHttpRequest() będzie wysyłającego, oczywiście zmieniając nazwę zapytania dla każdego z nich. Następnie uruchom plik setInterval(), który uruchamia się co x ilość milisekund i sprawdza właściwość length o wartości orequests. Jeśli jest równa zero, nie ma żadnych żądań, jeśli jest większa niż zero, żądania wciąż się pojawiają.Jeśli nie ma żadnych żądań, możesz wyczyścić przedział czasu przez clearInterval() lub go kontynuować.

Twój setInterval może wyglądać mniej więcej tak:

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

PO pytanie, jak to zrobić z rozszerzeniem Firefox, a nie z sieci strona używająca jQuery. – PleaseStand

+1

Przeczytałem dokumenty jquery na tych dwóch metod i wyglądają na miejscu na to, czego szukałem. Wciąż mam jedno pytanie: czy te zdarzenia będą wiązały się tylko z wywołaniami JQuery Ajax? Lub do każdego połączenia JavaScript Ajax? – Joel

+0

@idealmachine, naprawdę prosiłem o jakiekolwiek rozwiązanie, w tym o firefox lub biblioteki JavaScript. – Joel

0

Przeglądarka technicznie nie zawsze jest "zajęty". Biznes to bardzo subiektywny termin. Załóżmy, że główny wątek wykonuje prostą pętlę while, która blokuje wykonywanie. Mogłoby to zostać uznane zajęty, ale co zrobić, jeśli masz coś takiego:

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

przeglądarka nie jest blokowany (per se), więc czy strona jest „zajęty” jest bardzo niejasne. Co więcej, to nawet nie zaczyna dotykać pracowników sieci i kodu w chrome.

Będziesz musiał to robić, a nawet jeśli to zrobisz, prawdopodobnie nie będzie działać tak, jak tego oczekujesz. Ale powodzenia.

+0

Naprawdę mam na myśli sieci zajęte. Muszę wiedzieć, czy przeglądarka wysyła lub rejestruje dane. Zaktualizuję swój post, aby wyjaśnić. Dzięki. – Joel