Custom JavaScript tracking

This script simplifies the ability to use multiple tracking and analytics providers in your HTML and JavaScript.

The script was born when I was facing the task of enabling multiple user tracking and analytic scripts on the same page. I had to support Google Analytics, Clicky (formerly known as GetClicky), and a custom tracking script. I did not want to add multiple and different function calls on all my tags that needed to be tracked. What I ended up with was using data-attribute types to specify what I want to track.

The idea I came up with allows you to write the tracking tags only once in your HTML or JavaScript code, and then let the script take over and bind on the click-events to be able to fire off events to the respective providers.

So far I have added support for 4 tags:

TagDescription
data-tracking-category This is the category to put this tracked event in
data-tracking-action this is the action for the click event, e.g. 'clicked', 'played', 'stopped', 'downloaded', etc.
data-tracking-title this is the title that will be associated with the click-event, like a blog post title, e.g. 'How to enable tracking'
data-tracking-type this is the type of tracking you want to log this click as, and is ONLY being used by GetClicky statistics
- valid values are 'click', 'download', 'outbound', 'pageview', where 'click' is default if left out

Tagging examples

To give an example, let us start with a hyperlink tag:

<a href="http://www.adpilgrim.com" 
   data-track-title="User clicked on link to my blog" 
   data-tracking-action="click" 
   data-tracking-category="content-link" 
   data-track-type="click">Go to adpilgrim.com</a>

When the user clicks the above hyperlink, we will then track an event with the action-type click and the title User clicked on link to my blog, and categorize it as a content-link which in this case means it is located in the actual page content on the page. I use this to differentiate between different types of links, and would for example use data-tracking-category="navigation" for menu-related navigation hyperlinks.

Another example could be to track when a user starts to play a video from a custom made play button:

<div data-track-category="video" 
     data-tracking-action="play" 
     data-track-title="Video of our latest case study">View video</div>

Code examples

Now to some of the code. I have two JavaScript functions I use in order to bind the tracking of the data attributes with the click-event. The first one binds to a single DOM element type and look like this:

var bindTrackingToDomObject = function (domObject) {
	$(domObject).filter('[data-trackingcategory]').each(function () {
		// Unbind the event in case it has already been bound
		$(this).off('click', bindTrackingClick);
		// Bind the click event
		$(this).on('click', bindTrackingClick);
	});
};

This method I would use if I only wanted to bind 'a' tags in the HTML code, and would call the function like this:

bindTrackingToDomObject($('a'));

This would the find all 'a' tags and filter them, returning only the tags that have the attribute data-trackingcategory defined. Then, for each element returned, we ensure there is no other click-event defined on the object, and the re-bind the click-event to the object. The click-event function bindTrackingClick being invoked when the user click on the object is defined later in this article.

The next function will do the same event binding as the above, but will do so on all child elements defined in the object passed to the function:

var bindTrackingToDomChildObjects = function (domParentObject) {
	$(domParentObject).find('[data-tracking-category]').each(function () {
		// Unbind the event in case it has already been bound
		$(this).off('click', bindTrackingClick);

		// Bind the click event
		$(this).on('click', bindTrackingClick);
	});
};

The above method is the one I use the most to be honest, and I usually invoke it on the whole body-tag in my code:

bindTrackingToDomChildObjects($('body'));

When the event-binding is done in the above specified functions, you will notice they invoke the function bindTrackingClick on the click-event. This function has only one purpose - to simplify the code and to collect the data-attribute values of the element being clicked, and then invoke the track function that contain the actual tracking code:

var bindTrackingClick = function () {
	var category = $(this).data('trackingcategory');
	var action = $(this).data('trackingaction');
	var title = $(this).data('trackingtitle');
	var type = $(this).data('trackingtype');

	track(category, action, title, type);
};
As you can see the function track is being called with the values of the data-attributes defined on the element. The track function is implemented like this:
var track = function (category, action, title, type) {

	if (category == null || category == undefined || category == '') {
		throw 'parameter "category" cannot be null or empty';
	}

	if (action == null || action == undefined || action == '') {
		throw 'parameter "action" cannot be null or empty';
	}

	if (type != null && type != undefined) {
		if (type != 'click' || type != 'download' || type != 'outbound' || type != 'pageview') {
			throw 'parameter "type" is invalid. Supported types are 
			       "click", "download", "outbound", "pageview"';
		}
	}

	// The variable 'clicky' is a global variable for referencing GetClicky tracking
	try { clicky.log('/' + category + '/' + action, title, type); } catch (ex) { }

	// The variable '_gaq' is a global variable for referencing Google Analytics tracking
	try { _gaq.push(['_trackEvent', category, action, title]); } catch (ex) { }

	// Now we call our own tracking service
	try { your_custom_tracking_service(); } catch (ex) { }
};

That is more or less it - the code is pretty self-explanatory.

But as always, please feel free to reach out in case you have any questions or comments.

 
Comments

No comments yet.

Leave a comment