How dangerous is e.preventDefault () ;, and can it be replaced by keydown / mousedown tracking?

I am working on a tracking script for a fairly sophisticated CRM to track form actions in Google Analytics. I try to balance the desire to track form actions with to never prevent the form from working.

Now I know that doing something like this does not work.

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

The DOM is unloaded before it has the ability to process.

So, many code examples recommend something like this:

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

This is true in most cases , but it makes me nervous. What if something happens between e.preventDefault(); and when do I communicate with the proposal to send the DOM? I completely disrupted the form.

I reflected on some other analytics implementations, and I noticed 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')]); }); 

Basically, instead of interrupting form submission, unload it, assuming that if someone is silent or presses the Enter key, then this form is submitted. Obviously, this will lead to a certain number of false positives, but completely eliminates the use of e.preventDefault(); , which in my opinion eliminates the risk that I can ever prevent the successful submission of the form.

So my question is:

  • Is it possible to accept the standard form tracking fragment and prevent it from ever completely preventing the form from being submitted?
  • Is mousedown / keydown an alternative viable?
  • Are there any filing cases that he may miss? In particular, are there other ways to serve in addition to the mouse and keyboard? And will the browser always have time to handle javascript before starting to unload the page?
+7
source share
7 answers

They fall apart because Googleplex is terribly vibrant, and they ever wondered if this should happen, and now, of course, it does. Why don't you try:

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

That _gaq.push thigamajigger performs its elements sequentially, so you should be joking.

And no, I don’t know why I suddenly started talking like that.

+30
source

I use a different approach and generate a script for event tracking on the page resulting from the submission. You can call it delayed event tracking.

I wrote a blog post with all the details about my approach to tracking events in internal actions. It is biased towards Java-Struts, but you can get a general idea.

The rationale is that I want to track some things after they happened on the server side. In this case, after the form has been submitted and processed by the server.

What am I doing (very briefly):

  • Store events in the object associated with the session (list / queue)
  • Reset these events on the next page rendering (generate javascript and defame the queue)
+3
source

If you must have forms that always work, but tracking can be sacrificed, if absolutely necessary, you can just try / catch it.

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

e.preventDefault() should not be correct at the beginning of a function call. Why not just have an if to check if everything is working correctly, and only call e.preventDefault() if so. If any function in the chain does not return the expected result, set the submitted variable to false and do not interfere by default.

It can be a little harder to handle when it comes to anything asynchronous (like your setTimeout , for example, but there will be ways to make it pretty sure depending on how your code looks. So you can check if (_gaq.push) exist with if (_gaq.push) (for example). You cannot be 100% sure without testing every combination in every browser, but I believe that you can get a pretty satisfactory result with this.

+1
source

Another approach:

 var pageTracker; _gaq.push(function() { pageTracker = _gat._getTrackerByName(); }); $('form').submit(function(e){ pageTracker._trackEvent('Form', 'Submit', $(this).attr('action')); }; 

I would have guessed that the _trackEvent path would be synchronous, but I have not tested it.

0
source

Is there a reason why you cannot just send a call to Google Analytics from the server side based on the received POST message?

I do not know that your system is built-in, but, for example, this PHP project issues a GA call, thereby eliminating the problem of DOM unloading, the need to break the form, etc.

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

I understand that you may need to grab a cookie - can you write the value to a hidden field in the form before sending it?

0
source

To extend the answer to @Malvolio: As soon as gaq dispatches an event, the next element in the queue will be processed. This means that the HTTP event request may be interrupted on the client side, but GA will receive the request. Don't worry about blocking script execution until the response is complete. This is a scene of fire and forget.

0
source

All Articles