7

Estoy trabajando en un script de seguimiento para un CRM bastante sofisticado para el seguimiento de acciones de formulario en Google Analytics. Estoy tratando de equilibrar el deseo de rastrear acciones de forma con precisión con el necesita para nunca evitar que un formulario no funcione.¿Qué tan peligroso es e.preventDefault() ;, y puede ser reemplazado por el seguimiento de teclas/mousedown?

Ahora, sé que hacer algo como esto no funciona.

$('form').submit(function(){ 
_gaq.push(['_trackEvent', 'Form', 'Submit', $(this).attr('action')]); 
}); 

El DOM se descarga antes de que esto tenga la oportunidad de procesarse.

Por lo tanto, una gran cantidad de código de ejemplo recomienda algo como esto:

$('form').submit(function(e){ 
e.preventDefault(); 
var form = this; 
_gaq.push(['_trackEvent', 'Form', 'Submit', $(this).attr('action')]); 
//...do some other tracking stuff... 
setTimeout(function(){ 
form.submit(); 
}, 400); 
}); 

Ésta es fiable en most cases, pero me pone nervioso. ¿Qué sucede si ocurre algo entre e.preventDefault(); y cuándo me muevo para activar el envío basado en DOM? Rompí totalmente la forma.

He estado hurgando algunas otras implementaciones de análisis, y me he dado cuenta de something like this:

$('form').mousedown(function(){ 
_gaq.push(['_trackEvent', 'Form', 'Submit', $(this).attr('action')]); 
}); 
$('form').keydown(function(e){ 
    if(e.which===13) //if the keydown is the enter key 
    _gaq.push(['_trackEvent', 'Form', 'Submit', $(this).attr('action')]); 
}); 

Básicamente, en lugar de interrumpir el envío de formulario, adelantándose a ella por el supuesto de que si alguien está pasando el ratón hacia abajo o tecleando abajo en Entrar, que ese formulario se envía. Obviamente, esto dará como resultado una cierta cantidad de falsos positivos, pero elimina por completo el uso de e.preventDefault();, lo cual en mi opinión elimina el riesgo de que alguna vez evite que un formulario se envíe correctamente.

Por lo tanto, mi pregunta:

  • ¿Es posible tomar la forma estándar fragmento de seguimiento y evitar que de vez prevenir totalmente la forma de presentar ?
  • ¿Es viable la opción de mousedown/keydown ?
  • ¿Hay algún caso de presentación que se puede perder? Específicamente, ¿hay otras formas de enviar archivos además del mouse y el teclado? ¿Y el navegador siempre tendrá tiempo para procesar javascript antes de comenzar a descargar la página?

Respuesta

30

Los mentirosos de allí Googleplex son tremendamente brillantes y pensaron que algún día algo así iba a suceder y ahora, efectivamente, lo ha hecho. ¿Por qué no le das esto una buena oportunidad:

$('form').submit(function(e){ 
    e.preventDefault(); 
    var form = this; 
    _gaq.push(['_trackEvent', 'Form', 'Submit', $(this).attr('action')]); 
    //...do some other tracking stuff... 
    _gaq.push(function(){ 
    form.submit(); 
    }); 
    }); 

Eso _gaq.push thigamajigger ejecuta sus elementos de forma secuencial, por lo que debe estar bien broma.

Y no, no sé por qué de repente comencé a hablar así.

+4

Mmmm, déjame intentarlo de nuevo. La solución de simplemente esperar una cantidad arbitraria de tiempo y asumir que ahora es seguro abandonar la página está * garantizado * para (a) perder el tiempo de los usuarios o (b) fallar al salir temprano (las probabilidades de que adivine correctamente) cada vez puede ser ignorado). En su lugar, necesita una técnica mediante la cual se le notifica cuando se completa el seguimiento. Afortunadamente, Google Analytics Queue proporciona eso: todo lo que tiene que hacer es presionar un objeto de función al final de la cola. Una vez que todo lo que tiene delante en la cola se haya completado, esa función se ejecutará y enviará su formulario. – Malvolio

+7

Ahora me doy cuenta de que también puede estar preocupado por el hecho de que "algo de rastreo" falla y por lo tanto causa que nunca se envíe el formulario. Para eso, sus dos opciones son, envolver todo el código pero enviar en un bloque try-except, que es seguro por descuidado, o simple no invocar preventDefault hasta la última línea de la función, por lo que si hay un error, ganó No se le llamará y la presentación * debería * continuar, lo cual es elegante, pero debe probarse cuidadosamente. – Malvolio

+0

'_gaq.push ((function() {' debe ser '_gaq.push (function() {' – Thomas

0

Otro enfoque:

var pageTracker; 
_gaq.push(function() { 
    pageTracker = _gat._getTrackerByName(); 
}); 

$('form').submit(function(e){ 
    pageTracker._trackEvent('Form', 'Submit', $(this).attr('action')); 
}; 

Conjeturaría esta manera _trackEvent sería sincrónica pero yo no lo he probado.

+0

GA es asíncrono no es el problema. El aspecto asincrónico se refiere a la carga de la secuencia de comandos inicialmente, no a las llamadas posteriores. Una vez que carga ga.js, las llamadas '_gaq.push ('_ trackEvent', ...)' se ejecutan tan rápido como 'pageTracker._trackEvent (...)' – Yahel

+0

Si ese es el caso, podría considerar escribir su propia función trackEvent con un controlador de carga conectado a la imagen __utm.gif, sin embargo, creo que los controladores de carga para las imágenes no son tan confiables en algunos navegadores (por ejemplo,cuando se carga desde el caché no disparado, pero desde la carga del caché nunca debe ocurrir en este caso de todos modos). Una antigua función de pageTrack: http://code.google.com/p/google-analytics-js/source/browse/trunk/gajs.js?r=3 – Thomas

3

Uso un enfoque diferente y genero el script de seguimiento de eventos en la página resultante del envío. Podría llamarlo seguimiento de eventos diferidos.

Escribí un blog post con todos los detalles sobre mi enfoque para el seguimiento de eventos en acciones de back-end. Está sesgado hacia Java-Struts, pero puede obtener la idea general.

La razón es que quiero hacer un seguimiento de algunas cosas después de que ocurrieron en el lado del servidor. En este tipo de caso, después de que el formulario fue enviado y procesado por el servidor.

Lo que sí (muy resumido):

  • Almacenamiento de eventos en un objeto atado a la sesión (una lista/cola)
  • Flush estos eventos sobre la página siguiente rinden (generar el javascript y vacía la cola)
0

¿Existe alguna razón por la cual no se puede simplemente emitir la llamada a Google Analytics desde el servidor en función del POST que recibe?

No sé en qué está integrado su sistema, pero por ejemplo, este proyecto PHP emitiría una llamada a GA, eliminando así el problema de la descarga de DOM, la necesidad de romper el formulario, etc.

http://code.google.com/p/serversidegoogleanalytics/

que dan cuenta de que puede que tenga que capturar una cookie - es posible escribir el valor en un campo oculto en el formulario antes de su presentación?

+0

This podría funcionar para algunas personas, pero desafortunadamente, en este entorno CMS, no tengo acceso a secuencias de comandos del lado del servidor. Todo debe hacerse en JavaScript. – Yahel

+0

E incluso si pudiera, * usted * está pagando por los servidores; millones de clientes cada uno trae su propio cliente. – Malvolio

+0

Para la posteridad: el proyecto vinculado en esta respuesta se ha retirado, en su lugar, ver el proyecto más reciente http://code.google.com/p/php-ga/ – Funka

1

e.preventDefault() no tiene que estar justo al comienzo de la llamada a la función. ¿Por qué no simplemente tener una declaración if para verificar si todo está funcionando correctamente, y solo llama al e.preventDefault() si lo hace? Si alguna función en la cadena no devuelve el resultado esperado, establezca una variable submitted en false, y no impida el valor predeterminado.

Esto puede ser un poco más difícil de manejar cuando se trata de algo asíncrono (como su setTimeout, pero habrá formas de asegurarse bastante, dependiendo de cómo se vea el código. Para que pueda verificar si existen métodos con if (_gaq.push) (por ejemplo). No puede estar 100% seguro sin probar cada combinación en cada navegador, pero creo que puede obtener un resultado bastante satisfactorio con esto.

3

Si debe tener los formularios siempre funcionan pero siguiendo puede ser sacrificado si es absolutamente necesario, puede intentar/atraparlo.

$('form').submit(function(e){ 
    try{ 
     e.preventDefault(); 
     var form = this; 
     _gaq.push('_trackEvent', 'Form', 'Submit', $(this).attr('action')); 
     //...do some other tracking stuff... 
     setTimeout(function(){ 
      form.submit(); 
     }, 400); 
    } catch (e) { 
     form.submit(); 
    } 
}); 
+0

Implementado esta solución para el mismo problema y funcionó bien. Gracias. ¿Cuál es el motivo exacto por el que Google tiene un problema con los envíos de formularios y el seguimiento de eventos? Al principio pensé que se debía a la presentación del formulario. ng y la página se recarga demasiado rápido para que los datos se envíen a Google, pero incluso después de que agregué la lógica setTimeout, todavía estaba sucediendo. Solo cuando agregué la llamada 'e.preventDefault', todo comenzó a funcionar nuevamente. –

+1

Configurar el tiempo de espera es solo la mitad de la historia. Si configura un tiempo de espera para el envío del formulario, pero no e.preventDefault, entonces está permitiendo que el envío del formulario se realice de forma inmediata (como el evento predeterminado), que aún prevalece sobre la llamada al análisis. – audiodude

0

Para ampliar la respuesta de @Melvolio: Una vez que gaq envía el evento, se procesará el siguiente elemento de la cola. Esto significa que la solicitud HTTP del evento puede abortar en el lado del cliente, pero GA recibirá la solicitud. No se preocupe por bloquear la ejecución de scripts hasta que finalice la respuesta. Es un escenario de fuego y olvidar.

Cuestiones relacionadas