2011-01-12 25 views
38

Me gustaría medir un tiempo (en segundos en enteros o minutos en flotadores) que un usuario pasa en una página. Sé que hay un evento de descarga que puedo activar cuando salen de la página. Pero, ¿cómo conseguir un tiempo que ya hayan pasado allí?¿Cómo medir el tiempo pasado en una página?

Respuesta

27

Si utiliza Google Analytics, proporcionan esta estadística, aunque no estoy seguro de cómo la obtienen.

Si desea hacer su propia versión, necesitará tener alguna solicitud AJAX que se envíe a su servidor para iniciar sesión.

jQuery tiene un método .unload (...) se puede utilizar como:

$(document).ready(function() { 
    var start = new Date(); 

    $(window).unload(function() { 
     var end = new Date(); 
     $.ajax({ 
     url: "log.php", 
     data: {'timeSpent': end - start}, 
     async: false 
     }) 
    }); 
}); 

Ver más aquí: http://api.jquery.com/unload/

La única advertencia aquí es que utiliza evento beforeunload de Javascript, que doesn No siempre se dispara con tiempo suficiente para hacer una solicitud de AJAX como esta, por lo que es razonable que pierda una gran cantidad de datos.

Otro método sería sondear periódicamente el servidor con algún tipo de mensaje "STILL HERE" que se puede procesar de manera más consistente, pero obviamente mucho más costoso.

+2

Probablemente sea una mejor idea enviar una solicitud cuando el usuario carga JS por primera vez y otro cuando abandona la página. De esta forma no se puede hacer ningún tipo de truco. –

+1

Mejor sería establecer una variable '$ _SESSION' con la fecha , solo se actualiza cuando el servidor recibe la señal para actualizar.Como el '$ _SESSION'-var se establece cuando se carga la página, nunca es demasiado. – jdepypere

+0

Agregue 'async: false' a la llamada ajax anterior para evitar disparos intermitentes. – user217562

6

Creo que la mejor manera es almacenar el tiempo de carga y descarga de los controladores de eventos en las cookies, p. y luego analizarlos en scripts del lado del servidor

+0

probablemente la mejor manera, de otra manera sería tener un latido del corazón Javascript. – dvhh

+3

Esto solo funciona si el usuario va a otra página en el servidor. –

7

Diría que su mejor opción es realizar un seguimiento del tiempo de las solicitudes por ID de sesión en su servidor. El tiempo que el usuario pasó en la última página es la diferencia entre el momento de la solicitud actual y el momento de la solicitud anterior.

Esto no captará la última página de las visitas del usuario (es decir, cuando no vaya a haber otra solicitud), pero seguiría con este enfoque, ya que de lo contrario tendrías que enviar una solicitud en onunload, que sería extremadamente propenso a errores.

+0

Quiero rastrear una página de video con este enfoque, pero el problema es cuando el usuario abre una nueva página en una nueva pestaña, en este caso middel-ware detecta un nuevo acierto en la url. y obtener tiempo de la sesión y presionar DB, pero el usuario acaba de abrir una nueva pestaña no cerrar la pestaña actual y el método timeme.js y ajax tiene fallas :( – GrvTyagi

+0

Por ahora creo que la llamada ajax en cada 30 segundos funciona o no? – GrvTyagi

38

La respuesta aceptada es buena, pero (como alternativa) he puesto algo de trabajo en una pequeña biblioteca de JavaScript que mide el tiempo que un usuario está en una página web. Tiene el beneficio adicional de hacer un seguimiento más preciso (aunque no perfectamente) del tiempo que un usuario realmente está interactuando con la página. Ignora las veces que un usuario cambia a diferentes pestañas, se queda inactivo, minimiza el navegador, etc. El método de Google Analytics sugerido en la respuesta aceptada tiene el inconveniente (según tengo entendido) de que solo verifica cuando una nueva solicitud es manejada por su dominio. Compara el tiempo de solicitud anterior con el nuevo tiempo de solicitud y lo llama el "tiempo pasado en su página web". En realidad, no sabe si alguien está viendo su página, ha minimizado el navegador, ha cambiado las pestañas a 3 páginas web diferentes desde la última vez que cargó su página, etc.

Editar: He actualizado el ejemplo para que incluya la API actual uso.

Edición 2: Actualización de dominio en el proyecto se hospeda

https://github.com/jasonzissman/TimeMe.js/

Un ejemplo de su uso:

incluir en su página:

<!-- Download library from https://github.com/jasonzissman/TimeMe.js/ --> 
<script src="timeme.js"></script> 
<script type="text/javascript"> 
TimeMe.initialize({ 
    currentPageName: "home-page", // page name 
    idleTimeoutInSeconds: 15 // time before user considered idle 
}); 
</script> 

Si desea para informar los tiempos usted mismo a su servidor:

xmlhttp=new XMLHttpRequest(); 
xmlhttp.open("POST","ENTER_URL_HERE",true); 
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
var timeSpentOnPage = TimeMe.getTimeOnCurrentPageInSeconds(); 
xmlhttp.send(timeSpentOnPage); 

TimeMe.js también es compatible con el envío de datos de tiempo a través de WebSockets, por lo que no tienen que tratar de forzar una petición HTTP completa en el caso document.onbeforeunload.

+0

¡Realmente me gusta tu guión! Sin embargo, tiene un comportamiento extraño en la página de demostración: cuando cambio a una ventana diferente (el navegador no se minimiza, solo otra ventana tiene el foco), el temporizador sigue funcionando. ¿Esto es intencionado? – user1111929

+1

Gracias! La biblioteca depende de los eventos del navegador para contarlo cuando un usuario ha ganado/perdido el foco. Supongo que el navegador no informa el evento de "pérdida de foco" al cambiar de ventana porque los usuarios con múltiples monitores aún pueden ver el navegador. ¡Solo un pensamiento! –

+1

Una forma diferente de obtener esta métrica podría ser detectar movimientos del mouse y movimientos de desplazamiento/página, presionar teclas. Esta es una medida diferente. En las configuraciones de pantallas múltiples, a menudo tengo una página de referencia en un monitor, mientras trabajo en otra. La página de referencia no debe contar como tiempo-en-página ya que está allí, pero no lo estoy viendo. Con un poco de calibración, sospecho que un movimiento de ratón/presionar tecla/evento de desplazamiento por X segundos indicaría el tiempo aún en la página. X tiene entre 10 y 30 segundos, creo. –

1

Según la respuesta correcta, creo que esa no es la mejor solución. Porque de acuerdo a la documentación de jQuery:

El manejo exacto del evento de descarga ha variado desde la versión de versión de los navegadores. Por ejemplo, algunas versiones de Firefox activan el evento cuando se sigue un enlace, pero no cuando la ventana está cerrada. En el uso práctico de , el comportamiento debe probarse en todos los navegadores compatibles y en contraste con el evento de descarga previa similar.

Otra cosa es que no debe usarlo después de la carga de documentos porque el resultado de la resta de tiempo puede ser falso.

Así que la mejor solución es añadir al evento onbeforeunload en el extremo de la sección <head> así:

<script> 
var startTime = (new Date()).getTime(); 

window.onbeforeunload = function (event) { 
    var timeSpent = (new Date()).getTime() - startTime, 
     xmlhttp= new XMLHttpRequest(); 
    xmlhttp.open("POST", "your_url"); 
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
    var timeSpentOnPage = TimeMe.getTimeOnCurrentPageInSeconds(); 
    xmlhttp.send(timeSpent); 
}; 
</script> 

Por supuesto, si desea contar el tiempo usando un detector de inicio Puede utilizar:

https://github.com/serkanyersen/ifvisible.js/

TimeMe es una envoltura para el paquete que me pegue más arriba.

3

Además de la respuesta de Jason, aquí hay una pequeña porción de código que debería funcionar bien si usted prefiere no usar una biblioteca, considera cuando el usuario cambia de pestaña o enfoca otra ventana.

let startDate = new Date(); 
let elapsedTime = 0; 

const focus = function() { 
    startDate = new Date(); 
}; 

const blur = function() { 
    const endDate = new Date(); 
    const spentTime = endDate.getTime() - startDate.getTime(); 
    elapsedTime += spentTime; 
}; 

const beforeunload = function() { 
    const endDate = new Date(); 
    const spentTime = endDate.getTime() - startDate.getTime(); 
    elapsedTime += spentTime; 

    // elapsedTime contains the time spent on page in milliseconds 
}; 

window.addEventListener('focus', focus); 
window.addEventListener('blur', blur); 
window.addEventListener('beforeunload', beforeunload); 
+0

¿Considera el tiempo de inactividad? – kabrice

+0

@kabrice depende de lo que quiere decir con "inactivo". Si la pestaña está enfocada, no puede saber si el usuario está leyendo su página o no. Este fragmento básicamente obtiene el tiempo que el usuario enfocó la pestaña actual. Eso significa que su pestaña está en primer plano. – KeitIG

0
<body onLoad="myFunction()"> 
<script src="jquery.min.js"></script> 
<script> 
var arr = []; 
window.onbeforeunload = function(){ 
var d = new Date(); 
var n = d.getTime(); 
arr.push(n); 
var diff= n-arr[0]; 
var sec = diff/1000; 
var r = Math.round(sec); 
return "Time spent on page: "+r+" seconds"; 
}; 
function myFunction() { 
var d = new Date(); 
var n = d.getTime(); 
arr.push(n); 
} 
</script> 
Cuestiones relacionadas