7

Sto lavorando a uno script di monitoraggio per un CRM abbastanza sofisticato per il monitoraggio delle azioni del modulo in Google Analytics. Sto cercando di bilanciare il desiderio di tracciare accuratamente le azioni del modulo con il necessario per per evitare che un modulo non funzioni.Quanto è pericoloso e.preventDefault(); e può essere sostituito dal monitoraggio keydown/mouse?

Ora, so che fare qualcosa del genere non funziona.

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

Il DOM scarica prima che questo abbia la possibilità di elaborare.

Così, un sacco di codice di esempio suggerisce qualcosa di simile:

$('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); 
}); 

Questo è affidabile in most cases, ma mi rende nervoso. Cosa succede se succede qualcosa tra e.preventDefault(); e quando riesco ad attivare l'invio basato su DOM? Ho completamente rotto il modulo.

ho rovistando alcune altre implementazioni di analisi, e ho notato 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')]); 
}); 

In sostanza, invece di interrompere l'invio di modulo, si preempting assumendo che se qualcuno sta passando con il mouse verso il basso o la digitazione giù su Invio, di quel modulo è presentato. Ovviamente, questo si tradurrà in una certa quantità di falsi positivi, ma elimina completamente l'uso di e.preventDefault();, che nella mia mente elimina il rischio che io possa mai impedire a un modulo di inviare correttamente.

Quindi, la mia domanda:

  • E 'possibile prendere lo standard documento di accompagnamento frammento e impedire che da mai impedendo completamente la forma di presentare?
  • L'alternativa mousedown/keydown è valida?
  • Esistono casi di presentazione che potrebbero non essere disponibili? In particolare, ci sono altri modi per finire di inviare oltre al mouse e alla tastiera entrare? E il browser avrà sempre tempo per elaborare javascript prima di iniziare a scaricare la pagina?

risposta

30

Quelli là fuori che lì Googleplex sono orribili e si sono inventati un giorno che qualcosa del genere doveva accadere e ora, abbastanza sicuro, è successo. Perché non dare a questo un buon tentativo:

$('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(); 
    }); 
    }); 

Che _gaq.push thigamajigger esegue i suoi elementi in sequenza, quindi si dovrebbe andare bene per scherzo.

E no, non so perché ho improvvisamente iniziato a parlare in questo modo.

+4

Mmmm, fammi riprovare. La soluzione di aspettare solo una quantità arbitraria di tempo e supponendo che ora sia sicuro di lasciare la pagina è * garantita * per (a) sprecare il tempo degli utenti o (b) fallire andando in anticipo (le probabilità indovineranno correttamente ogni volta può essere ignorato). Invece hai bisogno di una tecnica con cui ti viene notificato quando il monitoraggio è completo. Fortunatamente, la coda di Google Analytics prevede che: tutto ciò che devi fare è premere un oggetto funzione alla fine della coda. Una volta completato tutto ciò che si trova nella coda, tale funzione verrà eseguita e invierà il modulo. – Malvolio

+7

Ora mi rendo conto che potresti anche essere preoccupato per il fatto che "alcuni elementi di monitoraggio" non siano riusciti e che quindi il modulo non venga mai inviato. Per questo le tue due scelte sono, avvolgi tutto il codice ma l'invio in un blocco try-except, che è sicuro da sciatto, o semplice non chiamare preventDefault fino all'ultima riga della funzione, quindi se c'è un errore, ha vinto essere chiamato e la presentazione * dovrebbe * continuare ancora, che è elegante ma dovrebbe essere attentamente testata. – Malvolio

+0

'_gaq.push ((function() {' dovrebbe essere '_gaq.push (function() {' – Thomas

0

Un altro approccio:

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

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

direi questo modo _trackEvent sarebbe sincrono ma non ho provato.

+0

GA asincrono non è il problema. L'aspetto asincrono si riferisce inizialmente al caricamento dello script, non alle chiamate successive. Una volta caricati ga.js, le chiamate '_gaq.push ('_ trackEvent', ...)' vengono eseguite con la stessa rapidità di 'pageTracker._trackEvent (...)' – Yahel

+0

Se questo è il caso, potresti prendere in considerazione la scrittura della tua funzione trackEvent con un gestore onload collegato all'immagine __utm.gif, tuttavia penso che i gestori di onload per le immagini non siano così affidabili in alcuni browser (ad esempioquando caricato dalla cache non viene attivato, ma dal caricamento della cache non dovrebbe mai accadere in questo caso comunque). Una vecchia funzione pageTrack: http://code.google.com/p/google-analytics-js/source/browse/trunk/gajs.js?r=3 – Thomas

3

Uso un approccio diverso e genera lo script di tracciamento eventi nella pagina risultante dall'invio. Puoi chiamarlo rintracciamento dell'evento rinviato.

Ho scritto un blog post con tutti i dettagli sul mio approccio al tracciamento degli eventi nelle azioni di back-end. È prevenuto nei confronti di Java-Struts, ma puoi ottenere l'idea generale.

La logica è che voglio tenere traccia di alcune cose dopo che sono accadute sul lato server. In questo tipo di caso, dopo che il modulo è stato inviato ed elaborato dal server.

Quello che (molto riassunto):

  • eventi Conservare in un oggetto legato alla sessione (un elenco/coda)
  • Flush questi eventi sulla pagina successiva rendono (generare il javascript e vuota la coda)
0

C'è un motivo per cui non puoi semplicemente chiamare la chiamata a Google Analytics dal lato server in base al POST che riceve?

Non so in che cosa sia integrato il tuo sistema, ma per esempio, questo progetto PHP emetterebbe una chiamata a GA, rimuovendo così il problema dello scaricamento del DOM, la necessità di rompere il modulo e così via.

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

mi rendo conto che potrebbe essere necessario acquisire un cookie - si potrebbe scrivere il valore in un campo nascosto in forma prima che sia presentata?

+0

potrebbe funzionare per alcune persone, ma sfortunatamente, in questo ambiente CMS, non ho accesso allo scripting lato server. Tutto deve essere fatto in JavaScript – Yahel

+0

E anche se potessi, * stai * pagando per i server; milioni di clienti portano ciascuno il proprio cliente – Malvolio

+0

Per i posteri: il progetto collegato in questa risposta è stato ritirato, ma si veda il progetto più recente http://code.google.com/p/php-ga/ – Funka

1

e.preventDefault() non deve essere corretto all'inizio della chiamata di funzione. Perché non avere solo una dichiarazione if per verificare se tutto funziona correttamente, e solo chiamare e.preventDefault() se lo fa. Se una qualsiasi funzione nella catena non restituisce il risultato previsto, impostare una variabile submitted su false e non impedire l'impostazione predefinita.

Questo potrebbe essere un po 'più difficile da gestire quando si tratta di qualcosa di asincrono (come il tuo setTimeout, ma ci saranno modi per essere abbastanza sicuri, a seconda di come appare il tuo codice. Quindi puoi verificare se esistono metodi con if (_gaq.push) (ad esempio). Non è possibile garantire il 100% senza testare ogni singola combinazione in ogni browser, ma ritengo che si possa ottenere un risultato abbastanza soddisfacente.

3

Se è necessario che i moduli funzionino sempre ma tracciamento può essere sacrificato se assolutamente necessario, si potrebbe semplicemente provare/prenderlo

$('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

Implementata questa soluzione per lo stesso problema e ha funzionato bene. Grazie. Qual è il motivo esatto per cui Google ha un problema con l'invio di moduli e il monitoraggio degli eventi? Inizialmente pensavo che fosse dovuto alla presentazione del modulo. ng e la pagina si ricaricano troppo velocemente perché i dati vengano inviati a Google, ma anche dopo aver aggiunto la logica setTimeout, stava ancora accadendo. Solo quando ho aggiunto la chiamata 'e.preventDefault' tutto ha ripreso a funzionare. –

+1

L'impostazione del timeout è solo metà della storia. Se imposti un timeout per l'invio del modulo, ma non e.preventDefault, l'invio del modulo avverrà immediatamente (come impostazione predefinita dell'evento), che interrompe comunque la chiamata all'analisi. – audiodude

0

Per espandere la risposta @ Malvolio: Una volta che gaq invia l'evento, verrà elaborato l'elemento successivo nella coda. Ciò significa che la richiesta HTTP dell'evento può interrompersi dal lato client, ma GA riceverà la richiesta. Non preoccuparti di bloccare l'esecuzione dello script fino al termine della risposta. È uno scenario di fuoco e dimentica.