2010-11-20 20 views
5

Estoy tratando de encontrar una manera de obtener si el navegador está ocupado actualmente desde JavaScript. Estoy buscando hacer una extensión de Firefox para inyectar un valor booleano o algo si la página actual está cargando algo (ya sea a través de ajax o solo cargas de página normales), o lo mismo con un script de Greasemonkey, o a través de alguna API de JavaScript (esto haría ser la mejor solución, pero por lo que puedo ver, nada de eso existe).Obtener si el navegador está ocupado

Me preguntaba cuál es la mejor manera de hacer esto sería. He estado buscando los tutoriales de Firefox Addon/Greasemonkey para hacer algo como esto y no puedo encontrar nada. ¿Alguien tiene consejos o recursos a los que puedan dirigirme o mejores soluciones para resolver esto?

Gracias

Editar: y por ocupado, que en su mayoría sólo necesitan saber si el navegador está enviando o recibiendo datos de un servidor.

Respuesta

2

Esto es lo que creo que terminaré haciendo. Esta solución es como el que Alex sugirió con los eventos jQuery, excepto que funciona con cualquier cosa que utiliza el XMLHttpRequest (Incluyendo 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

¡Pensé en comentar y decir que 3 años después, todavía estamos usando este enfoque básico y funciona de maravilla! – Joel

+0

¡Esto es realmente asombroso! ¡Gracias! Realmente útil para algunas pruebas/raspado automáticos de sitios web. – Evers

4

jQuery, un gran marco de JavaScript para la manipulación DOM y que realizan llamadas ajax, ofrece dos grandes ganchos para determinar cuándo las llamadas ajax están en curso:

$.ajaxStart() y $.ajaxStop()

Ambos ganchos tener una función de controlador se llamará cuando esté a punto de comenzar una llamada ajax, y cuando hayan cesado todas las llamadas ajax, respectivamente. Estas funciones se pueden vincular a cualquier elemento en la página. Puede establecer un valor booleano global en su manejador $.ajaxStart() en true y establecerlo de nuevo en false en su controlador $.ajaxStop().

A continuación, puede comprobar que la bandera booleana y determinar si las llamadas ajax están en curso.

Algo a lo largo de estas líneas:

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

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

En cuanto a la determinación de cuando el navegador carga la página actual, se puede comprobar document.readyState. Devuelve una cadena de "loading" mientras se carga el documento y una cadena de "complete" una vez que se ha cargado. Puede vincular un controlador al document.onreadystatechange y establecer un booleano global que indicará si el documento aún se está cargando o no.

Algo como esto:

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

EDIT:

Parece que $.ajaxStart() y $.ajaxStop() no trabajo para las llamadas ajax invocados sin jQuery. Todos los objetos XMLhttprequest tienen un evento llamado readystatechange al que puede adjuntar un controlador. Puede utilizar esta funcionalidad para determinar si se realiza o no esa llamada individual. Puede insertar todas las referencias a llamadas pendientes en una matriz, y en un setInterval() verificar la longitud de la matriz. Si es> 1, hay llamadas ajax abiertas. Es un enfoque rudo y solo una forma de resolverlo. Probablemente haya otras formas de hacer esto. Pero aquí está el enfoque general:

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

hacer lo anterior para cada XMLHttpRequest() va a enviar, por supuesto, cambiar el nombre de solicitud para cada uno. A continuación, ejecute un setInterval() que se ejecuta cada x cantidad de milisegundos y comprueba la propiedad de longitud de orequests. Si es igual a cero, no hay solicitudes, si es mayor que cero, las solicitudes siguen ocurriendo.Si no hay solicitudes, puede borrar el intervalo a través del clearInterval() o seguir ejecutándolo.

Su setInterval podría ser algo como esto:

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

El PO preguntó cómo hacer esto desde una extensión de Firefox, no de una web página que usa jQuery. – PleaseStand

+1

Leo los documentos de jquery en esos dos métodos y miran a lo que estaba buscando. Todavía tengo una pregunta: ¿esos eventos solo se unirán a las llamadas de Jquery Ajax? O a cualquier llamada Ajax de JavaScript? – Joel

+0

@idealmachine, realmente estaba pidiendo cualquier solución, incluidas las bibliotecas de Firefox o JavaScript. – Joel

0

El navegador técnicamente no es siempre "ocupado". Negocios es un término muy subjetivo. Supongamos que el hilo principal está realizando un simple bucle while que bloquea la ejecución. Esto podría ser considerado como ocupado, pero lo que si tiene algo como esto:

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

no está siendo bloqueado El navegador (per se), por lo que si la página es "ocupado" es muy claro. Además, eso ni siquiera comienza a tocar a los trabajadores de la web y el código en el cromo.

Va a ser muy difícil hacerlo, e incluso si lo hace, es probable que no funcione como espera. Buena suerte, no obstante.

+0

Realmente me refiero a la red ocupada. Necesito saber si thebrowser está enviando o grabando datos. Actualizaré mi publicación para aclarar. Gracias. – Joel

Cuestiones relacionadas