2010-11-20 32 views
5

J'essaie de trouver un moyen d'obtenir si le navigateur est actuellement occupé à partir de JavaScript. Je cherche à faire une extension Firefox pour injecter une valeur booléenne ou quelque chose si la page en cours charge quelque chose (soit par ajax ou simplement des charges de page normales), soit la même chose avec un script Greasemonkey, ou via une API JavaScript (ceci être la meilleure solution, mais d'après ce que je peux voir, rien de ce genre n'existe). Je me demandais quelle serait la meilleure façon de le faire. J'ai cherché des tutoriels Firefox Addon/Greasemonkey pour faire quelque chose comme ça et je ne trouve rien. Est-ce que quelqu'un a des conseils ou des ressources qu'ils pourraient me diriger vers ou de meilleures solutions pour résoudre ce problème?Obtenir si le navigateur est occupé

Merci

Edit: et par occupé, je viens surtout besoin de savoir si le navigateur envoie ou reçoit des données d'un serveur.

Répondre

2

Voici ce que je pense que je vais finir par faire. Cette solution est comme celui Alex suggéré avec les événements Jquery, sauf qu'il fonctionne avec tout ce qui utilise le XMLHttpRequest (y compris 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

Je pensais commenter et dire que 3 ans plus tard, nous utilisons toujours cette approche de base et cela fonctionne très bien! – Joel

+0

C'est vraiment génial! Merci! Vraiment utile pour certains tests/grattage automatiques de sites Web. – Evers

4

jQuery, un framework javascript pour la manipulation DOM et effectuant des appels ajax, fournit deux grands crochets pour déterminer quand les appels ajax sont en cours:

$.ajaxStart() et $.ajaxStop()

Ces deux crochets prendre une fonction de gestionnaire cela sera appelé quand un appel ajax est sur le point de démarrer, et quand tous les appels ajax auront cessé, respectivement. Ces fonctions peuvent être liées à n'importe quel élément de la page. Vous pouvez définir une valeur booléenne globale dans votre gestionnaire $.ajaxStart() sur true et la définir sur false dans votre gestionnaire $.ajaxStop().

Vous pouvez ensuite vérifier ce drapeau booléen et déterminer si des appels ajax sont en cours.

Quelque chose le long de ces lignes:

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

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

En ce qui concerne la détermination lorsque le navigateur charge la page en cours, vous pouvez vérifier document.readyState. Il renvoie une chaîne de "loading" pendant le chargement du document et une chaîne de "complete" une fois qu'il a été chargé. Vous pouvez lier un gestionnaire à document.onreadystatechange et définir un booléen global qui indiquera si le document est toujours en cours de chargement ou non.

Quelque chose comme ceci:

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

EDIT:

Il semble que $.ajaxStart() et $.ajaxStop() ne fonctionnent pas pour les appels ajax appelés sans jQuery. Tous les objets XMLhttprequest ont un événement appelé readystatechange auquel vous pouvez attacher un gestionnaire. Vous pouvez utiliser cette fonctionnalité pour déterminer si cet appel individuel est effectué ou non. Vous pouvez placer toutes les références aux appels en attente sur un tableau et, dans un setInterval(), vérifier la longueur de ce tableau. Si c'est> 1, il y a des appels ajax debout. C'est une approche approximative, et seulement une façon d'y arriver. Il y a probablement d'autres façons de le faire. Mais voici l'approche générale:

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

Est-ce que ci-dessus pour chaque XMLHttpRequest() vous enverrez, bien sûr changer le nom de la demande de chacun. Ensuite, exécutez un setInterval() qui s'exécute toutes les x millisecondes et vérifie la propriété length de orequests. Si elle est égale à zéro, aucune demande n'est en cours, si elle est supérieure à zéro, les demandes sont toujours en cours.Si aucune demande ne se produit, vous pouvez effacer l'intervalle par clearInterval() ou le laisser en cours d'exécution.

Votre setInterval pourrait ressembler à ceci:

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

L'OP a demandé comment faire cela à partir d'une extension Firefox, et non d'une bande page qui utilise jQuery. – PleaseStand

+1

J'ai lu les docs de jquery sur ces deux méthodes et ils ont l'air sur pour ce que je cherchais. J'ai encore une question cependant: ces événements se lieront-ils uniquement aux appels Jquery Ajax? Ou à tout appel JavaScript Ajax? – Joel

+0

@idealmachine, je demandais vraiment une solution, y compris les bibliothèques firefox ou JavaScript. – Joel

0

Le navigateur est techniquement jamais "occupé". Les affaires sont un terme très subjectif. Supposons que le thread principal exécute une simple boucle while qui bloque l'exécution. Cela pourrait être considéré comme occupé, mais si vous avez quelque chose comme ceci:

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

Le navigateur n'est pas bloqué (en soi), de sorte que si la page est « occupé » est très floue. En outre, cela ne commence même pas à toucher les travailleurs Web et le code dans le chrome.

Vous allez avoir du mal à faire cela, et même si vous le faites, cela ne fonctionnera probablement pas comme prévu. Bonne chance, néanmoins.

+0

Je veux vraiment dire réseau occupé. J'ai besoin de savoir si le navigateur envoie ou enregistre des données. Je vais mettre à jour mon message pour clarifier. Merci. – Joel