2010-11-29 13 views
5

Quiero contar cuánto tiempo pasan los visitantes en una página determinada y almacenarlo en mi base de datos MySQL.El evento onunload de JS no siempre funcionará

pensé en que acaba de empezar un temporizador en window.onload así:

window.onload= startCount; 
window.onunload= sendCount; 

var b=0; 
var y; 
function startCount() { 
    document.getElementById('livecount').innerHTML=b; 
    b=b+1; 
    y=setTimeout("startCount()",1000); 
} 

y después de que el visitante abandona la página (window.onunload), estoy enviando el tiempo a través de un XMLHttpRequest para un PHP archivo, que lo almacenará en mi base de datos:

function sendCount() { 
    clearTimeout(y);  
if (window.XMLHttpRequest) 
    {// code for IE7+, Firefox, Chrome, Opera, Safari 
    xmlhttp=new XMLHttpRequest(); 
    } 
else 
    {// code for IE6, IE5 
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    } 
xmlhttp.open("GET","count.php?q="+b,true); 
xmlhttp.send(); 
} 

El problema es que no siempre funciona. Diría que funciona como 3 de cada 10 veces. Lo intento. ¿Podría ser que no queda suficiente tiempo para que PHP y SQL se ejecuten por completo?

Respuesta

0

onunload no es una forma confiable de rastrear ... bueno, casi cualquier cosa. por ejemplo, vea http://www.google.com/support/forum/p/Google+Analytics/thread?tid=6496cd5d4b627c0e&hl=en

En cuanto a la solución del problema, la mejor manera es seguir la última vez que el usuario estuvo en la página. Por ejemplo, llame al rastreador cada minuto desde el cliente. Los sistemas de análisis como Google Analytics simplemente suponen que el usuario se quedó después de la última página que se envió. Es decir. si leo la página y luego hago clic en algo, refresca el contador. Pero si no ocurren éxitos posteriores, eso significa que me fui.

+0

OK, veo ... ni siquiera funciona cuando salgas de la página escribiendo en una URL diferente: cierta página)? – LightDark

4

Como onunload no es confiable, consideraría una solución AJAX. No soy un experto en esto en absoluto, pero el pensamiento que viene a la mente es un ping a tu contador de vez en cuando. No haría ping a tu contador cada segundo, ya que parece excesivo.

Me descomponer veces en duraciones que le interesan, tales como < 5 segundos, 30 segundos, < < 1 minuto, 5 minutos <, 5+ minutos.

Entonces me gustaría escribir un fragmento de código JavaScript, así:

window.onload = soCounter; 

var iter=0; 
var times=[0,5,30,60,300]; // Your duration choices 

function doCounter() { 

    sendCountPing(times(iter)); 

    iter++; 

    if(iter < times.length) { 
     setTimeout(doCounter, times[iter]*1000); 
    } 
} 

function sendCountPing(dur) { 
    if (window.XMLHttpRequest) 
    { // code for IE7+, Firefox, Chrome, Opera, Safari 
     xmlhttp=new XMLHttpRequest(); 
    } 
    else 
    { // code for IE6, IE5 
     xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 
    } 

    xmlhttp.open("GET","count.php?q="+b,true); 
    xmlhttp.send(); 

} 

El truco es que por cada count.php?q=30 que se envía, es necesario restar uno a partir del recuento count.php?q=5. Esto no tiene que ser programático, es fácil de procesar.

Para aclarar, si tuviera 3 visitantes, un gasto de 3 segundos, un gasto de 20 segundos, y uno de gasto 30 minutos, verá los siguientes aspectos: sentido

0: 3 // 3 people spent at least 0 seconds 
    5: 2 // 2 people spent at least 5 seconds 
30: 1 
60: 1 
300: 1 // 1 person spent at least 5 minutes 

Hacer?

+0

Muchas gracias por su amplia respuesta. Sí, tiene sentido, por supuesto, pero no es lo que quiero hacer. Mi objetivo es hacer una suma de todo el tiempo que los usuarios han gastado en la página (entonces no se requieren estadísticas). Pensé simplemente en enviar la hora al DB con AJAX cada 5 segundos más o menos, pero ¿no es una gran pérdida de poder de cómputo para los servidores? – LightDark

+2

Como se dijo en otro lugar, si este es el objetivo , es mejor que haga pings de 30 segundos a un script de servidor ligero. La frecuencia de los pings depende del tipo de sitio que tenga, pero en los sitios normales, muchas visitas son s de 30 segundos. Tal vez podría hacer un ping de 5 segundos y luego disminuirlo a un ping de 30 segundos. De cualquier manera, nunca obtendrás un número exacto. –

1

para cuando se ejecuta el controlador onload, la página está en proceso de desinstalación. No estoy seguro de qué garantías tiene para el estado del DOM u otros servicios, pero ciertamente no puede esperar que ocurran eventos de asincronización o tiempos de espera excedidos. Aunque no forma parte del estándar, la mayoría (¿todos?) Navegadores actuales proporcionan un gancho onbeforeunload que funciona de manera muy similar a otros manejadores de eventos, excepto que también puede devolver falso para cancelar la descarga si así lo desea.

+0

Gracias por la respuesta, lo intenté antes de la descarga y no funcionó en absoluto con Chrome:/ – LightDark

+0

Interesante. ¿Deberia trabajar? http://stackoverflow.com/questions/803887/can-i-pop-up-a-confirmation-dialog-when-the-user-is-closing-the-window-in-safari – peller

1

Puede configurar un temporizador como se sugiere que se ejecuta tantas veces como quiera (unos pocos segundos más o menos), y almacenar la información en una cookie (o cookies). Puede enviar esta información al servidor si es necesario cuando desea hacer algo más que mostrar el valor al usuario. Por lo tanto, no lo envíe al servidor cada ciclo, simplemente envíelo al servidor cuando desee hacer algo con esa información (como mostrarle al usuario una lista de todo el tiempo que pasó en varias páginas de su sitio).

+0

Gracias por su respuesta. Lo que estoy tratando de hacer es simplemente obtener la suma del tiempo invertido por todos los visitantes en una página determinada y almacenar esta información en la base de datos (no tiene que ser visible para el usuario). Al mismo tiempo, esta información debe ser lo más precisa posible y no debe requerir demasiadas solicitudes DB (no quiero enviar y guardar el tiempo como cada segundo). – LightDark

+1

No hay una manera confiable de hacer esto que yo sepa sin llamadas ajax regulares al servidor, lo que naturalmente necesitaría mantener a una frecuencia razonable. Si el punto final de esa llamada es muy liviano, no debería ser demasiado importante. De manera realista, CUALQUIER método no será muy preciso, así que creo que una resolución de 30 segundos o más es todo lo que podrías esperar de todos modos. Incluso si el evento de descarga funcionara correctamente, los datos se verían contaminados con apariciones como que las personas se alejaran de su computadora con la página web todavía activa, cambien de pestaña a otros sitios, etc., etc. –

0

Otra opción es guardar los datos en localStorage/cookie y enviarlos la próxima vez que el usuario acceda al sitio web; asumiendo que el usuario se queda o alguna vez regresa a su sitio web.

Es mejor usar Date() calc en lugar de setInterval/setTimeout para contar el tiempo.
Es mejor usar addEventListener en lugar de onload = func.

sendPreviousStats(); 
window.addEventListener('load',loadFunc); 
window.addEventListener('unload',leaveFunc); 

function loadFunc() { 
    window.startTime = new Date(); 
} 

function leaveFunc() { 
    var msec = new Date().getTime()-window.startTime.getTime(); 
    var seconds = Math.round(msec/1000); 
    localStorage.setItem('leaveSeconds',seconds); 
} 

function sendPreviousStats() { 
    var duration = localStorage.getItem('leaveSeconds'); 
    if (duration !== null && duration !== undefined) { 
     localStorage.removeItem('leaveSeconds'); 
     sendCountPing(duration); 
    } 
} 
Cuestiones relacionadas