Skip to content

Instantly share code, notes, and snippets.

@sindre
Created December 1, 2009 15:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sindre/246358 to your computer and use it in GitHub Desktop.
Save sindre/246358 to your computer and use it in GitHub Desktop.
Monitor events with Google Analytics ga.js tracking code
/* pGA - Monitor events with Google Analytics ga.js tracking code
* port of jGoogleAnalytics (version 1.0 2008-06-18) to use prototype
*
* @author: Sindre Wimberger // wimberger@echonet.at
* @version: 1.0 2009-05-20
*
* Requires Prototype 1.6.1 or higher
*
* Uses some elements of gaTracker (c)2007 Jason Huck/Core Five Creative
* http://plugins.jquery.com/files/jquery.gatracker.js_0.txt
* and jGoogleAnalytics David Simpson david.simpson [at] nottingham.ac.uk
* http://davidsimpson.me/2008/06/18/jgoogleanalytics-google-analytics-integration-for-jquery/
*
* @param {String} trackerCode
* @param {Object} options see setings below
*
* usage:
* new pGA(( 'UA-XXXXXX-X');
* new pGA(( 'UA-XXXXXX-X', {anchorClick: true, pageViewsEnabled: false} );
*
*/
var pGA = Class.create({
options: {
anchorClick: false, // adds click tracking to *all* anchors
clickEvents: null, // e.g. {'.popup': '/popup/nasty'}
crossDomainSelector: false, // e.g. 'a.crossDomain'
domainName: false, // e.g. 'nottingham.ac.uk'
evalClickEvents: null, // e.g. {'#menu li a': "'/tabs/'+ $(this).text()"}
evalSubmitEvents: null, // e.g. {'#menu li a': "'/tabs/'+ $(this).text()"}
extensions: [
'pdf','doc','xls','csv','jpg','gif', 'mp3',
'swf','txt','ppt','zip','gz','dmg','xml'
], // download extensions to track
external: '/external/', // prefix to add to external links
mailto: '/mailto/', // prefix to add to email addresses
download: '/download/', // prefix to add to downloads
organicSearch: null, // e.g. {'search-engine': 'query-term', 'google.nottingham.ac.uk': 'q'}
pageViewsEnabled: true, // can be disabled e.g. if only tracking click events
sampleRate: null, // e.g. 50 - set the sample rate at 50%
submitEvents: null // e.g. {'#personUK': '/personsearch/uk'}
},
/**
* load ga.js and add the tracking code
*/
initialize: function(trackerCode, options)
{
this.trackerCode = trackerCode;
this.options = Object.extend(this.options, options || {});
try
{
var gaJsHost = (
('https:' == document.location.protocol)
? 'https://ssl.'
: 'http://www.'
) + 'google-analytics.com/ga.js';
var script = new Element('script', { 'src': gaJsHost});
var gaTrack = function() {
if (!script.readyState || /loaded|complete/.test(script.readyState)) {
// var pageTracker = _gat._getTracker(gaTrackerId);
// pageTracker._trackPageview();
this.setupTracking();
}
};
script.observe('load', gaTrack);
script.observe('readystatechange', gaTrack);
document.body.appendChild(script);
}
catch(err)
{
// log any failure
// console.log('Failed to load Google Analytics:' + err);
}
},
setupTracking: function ()
{
// Get the tracking code
this.pageTracker = _gat._getTracker(this.trackerCode);
// Track visitor across subdomain
if (this.options.topLevelDomain)
{
this.pageTracker._setDomainName(this.options.topLevelDomain);
}
// Set the sample rate - for very busy sites
if (this.options.sampleRate)
{
this.pageTracker._setSampleRate(this.options.sampleRate);
}
// Track visitor across domains
if (this.options.crossDomainSelector)
{
// ignore domain names
this.pageTracker._setDomainName('none');
this.pageTracker._setAllowLinker(true);
// Add submit event to form selector e.g. form.crossDomain
$$('form' + this.options.crossDomainSelector).observe('submit', function(form)
{
this.pageTracker._linkByPost(form);
// console.debug('crossDomain ._linkByPost');
}.bind(this)
);
// Add a click event to anchor selector e.g. a.crossDomain
$$('a' + this.options.crossDomainSelector).observe('click', function(anchor)
{
this.pageTracker._link( $(anchor).attr('href') );
// console.debug('crossDomain ._link: ' + $(this).attr('href'));
}.bind(this)
);
// Add click event to link
}
// Add organic search engines as required
if (this.options.organicSearch)
{
this.options.organicSearch.each(function(pair)
{
this.pageTracker._addOrganic(pair.key, pair.value);
// console.debug('_addOrganic: ' + pair.key);
}.bind(this)
);
}
// check that this is the correct place
this.pageTracker._initData();
// console.debug('_initData');
this.addTracking(this.pageTracker);
},
addTracking function() {
// 1. Track event triggered 'views'
// loop thru each link on the page
if (this.options.anchorClick)
{
// From: http://plugins.jquery.com/files/jquery.gatracker.js_0.txt
$$('a').each(function(anchor){
var u = anchor.href;
if(typeof(u) != 'undefined'){
var newLink = this.decorateLink(u);
// if it needs to be tracked manually,
// bind a click event to call GA with
// the decorated/prefixed link
if (newLink.length)
{
$(this).observe('click', function()
{
this.pageTracker._trackPageview(newLink);
// console.debug('anchorClick: ' + newLink);
}.bind(this)
);
}
}
}.bind(this));
}
// loop thru the clickEvents object
if (this.options.clickEvents)
{
this.options.clickEvents.each(function(pair){
$(pair.key).observe('click', function(){
this.pageTracker._trackPageview(pair.value);
// console.debug('clickEvents: ' + val);
}.bind(this));
}.bind(this));
}
// loop thru the evalClickEvents object
if (this.options.evalClickEvents)
{
this.options.evalClickEvents.each(function(pair){
$(pair.key).observe('click', function(){
evalVal = eval(pair.value)
if (evalVal != '')
{
this.pageTracker._trackPageview(evalVal);
// console.debug('evalClickEvents: ' + evalVal);
}
}.bind(this));
}.bind(this));
}
// loop thru the evalSubmitEvents object
if (this.options.evalSubmitEvents)
{
this.options.evalSubmitEvents.each(function(pair){
$(pair.key).observe('submit',function(){
evalVal = eval(pair.value)
if (evalVal != '')
{
this.pageTracker._trackPageview(evalVal);
// console.debug('evalSubmitEvents: ' + evalVal);
}
}.bind(this));
}.bind(this));
}
// loop thru the submitEvents object
if (this.options.submitEvents)
{
this.options.submitEvents.each(function(pair){
$(pair.key).observe('submit', function(){
this.pageTracker._trackPageview(pair.value);
// console.debug('submitEvents: ' + val);
}.bind(this));
}.bind(this));
}
// 2. Track normal page views
if (this.options.pageViewsEnabled)
{
this.pageTracker._trackPageview();
// console.debug('pageViewsEnabled');
}
else
{
// console.debug('pageViewsDisabled');
}
},
// From: http://plugins.jquery.com/files/jquery.gatracker.js_0.txt
// Returns the given URL prefixed if it is:
// a) a link to an external site
// b) a mailto link
// c) a downloadable file
// ...otherwise returns an empty string.
decorateLink: function(u)
{
var trackingURL = '';
if (u.indexOf('://') == -1 && u.indexOf('mailto:') != 0)
{
// no protocol or mailto - internal link - check extension
var ext = u.split('.')[u.split('.').length - 1];
var exts = this.options.extensions;
for(i=0; i < exts.length; i++)
{
if(ext == exts[i])
{
trackingURL = this.options.download + u;
break;
}
}
}
else
{
if (u.indexOf('mailto:') == 0)
{
// mailto link - decorate
trackingURL = this.options.mailto + u.substring(7);
}
else
{
// complete URL - check domain
var regex = /([^:\/]+)*(?::\/\/)*([^:\/]+)(:[0-9]+)*\/?/i;
var linkparts = regex.exec(u);
var urlparts = regex.exec(location.href);
if (linkparts[2] != urlparts[2])
{
trackingURL = this.options.external + u;
}
}
}
return trackingURL;
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment