Google Analytics initially uses a _gaq
[object Array]
. Passing an array to a function is in JavaScript passing an object, thus by reference.
(Edit: As pointed out in answers, the reference is passed by value. See https://stackoverflow.com/a/5314911/120521 for more details on reference/value passing in JavaScript.)
The code below uses jQuery to wait for the DOM to load, then attach a change
event which will send a virtual pageview to Google Analytics once the user changes <input/>
field.
var _gaq = _gaq || [];
_gaq.push(['_setAccount', _gAAccount]);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
var Tracking = {
trackInputs: function ($, gaObject) {
var inputs = $('#signUp').find('input');
inputs.bind('change', function () {
gaObject.push(['_trackPageview', '/virtual/input']);
console.log(gaObject); // Outputs:
// [Array[2], Array[1], Array[2]]
// i.e. _setAccount, _trackPageview,
// and _trackPageview calls.
});
}
};
jQuery(document).ready(function($) {
Tracking.trackInputs($, _gaq);
});
// ... DOM begins below
However, as can be seen in the comment above, the trackInputs()
method prints the 'original' array. Ordinarily what the Google Analytics script does is it changes the _gaq
array into a _gaq
object and alters the push prototype for the object to have it make requests to the Google Analytics servers once a new call is pushed to the object.
Why isn't this alteration also passed by reference into trackInputs()
?
I realise the loaded Google Analytics script will (or will it?) occur after the Tracking.trackInputs()
definition, so the browser might not understand it is now an [object object]
but will persist in thinking it was the original [object Array]
. But, then it is not a reference anymore, is it?
(Using the _gaq
object globally (not passing it to the method at all) would solve the problem, but I want to understand why this doesn't work.)
jQuery(document).ready(function($) {
Tracking.trackInputs($, _gaq);
});
Since the DOM is ready before GA is loaded, the reference of _gaq
still points to an ordinary array, which is then perpetuated by the local symbol gaObject
inside the trackInputs()
function.
trackInputs: function ($, gaObject) {
After GA has loaded, the global symbol _gaq
is replaced by the tracker, but gaObject
still points to the old symbol.
You could use the "ready" feature of GA to call your trackInputs()
function instead of using $(document).ready(...)
:
_gaq.push(function() {
// when this runs, the tracker would have initialized;
Tracking.trackInputs($, _gaq);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With