Chris Mendez in Javascript, For Developers

Javascript Outbound Link Tracker

Scripts used to record whenever users click an external link.

New Google Analytics gtag Tracker

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script charset="utf-8" type="text/javascript">
$(document).ready(function(){
	//http://obscurejavascript.tumblr.com/post/74389765835/javascript-string-interpolation
	var $$ = function() {
	    var args =  Array.prototype.slice.call(arguments);
		console.log(arguments);
	    for (var i = 1; i < args.length; i += 1)
	        args[0] = args[0].split('$' + i).join(args[i]);

	    return args[0];
	};
	$("a").bind("click", onLinkClickHandler);
	function onLinkClickHandler( e ){
		var currentHREF = $(this).attr('href');
		var pathname = window.location.hostname;
        // Interpolation magic to simplify Regex
		var matchExp = $$('/$1|$2|$3/', pathname, pathname.replace("www.",""), "#");
		console.log(matchExp);
		if ( !currentHREF.match(matchExp) ) { 
			gtag('event', 'Click', {
			  'event_category': 'Outbound',
			  'event_label': currentHREF
			});
		}
		//return false;
	}	
});
</script>

Old Style Google Analytics

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script charset="utf-8" type="text/javascript">
$(document).ready(function(){
	$("a").bind("click", onLinkClickHandler);
	function onLinkClickHandler( e ){
		var currentHREF = $(this).attr('href');
		var matchExp = /www.chrisjmendez.com|chrisjmendez.com|#/;
    	var pathname = window.location.pathname;
		console.log(currentHREF)
		if ( !currentHREF.match(matchExp) ) { _gaq.push(['_trackEvent', 'external', currentHREF]) }
		//return false;
	}	
});
</script>

Advanced Example

Suppose you have a website with over 100 pages and you don't want to add individual custom trackers. Instead, you'd like to have Javascript wait for the HTML page to load, then scan all the links on the page itself and if there's an external link, append campaign information as if you were creating something custom using Google Campaign Builder.

Create a file named /js/CampaignTracker.js and call it from this script in your footer.

<script charset="utf-8" type="text/javascript">
$(document).ready(function(){
	$.getScript("/js/CampaignTracker.js");
    var $$ = function() {
	    var args =  Array.prototype.slice.call(arguments);
		console.log(arguments);
	    for (var i = 1; i < args.length; i += 1)
	        args[0] = args[0].split('$' + i).join(args[i]);

	    return args[0];
	};
	//Campaign Tracker is the code you see below. 
	$.getScript("/js/CampaignTracker.js");
	$("a").bind("click", onLinkClickHandler);
	function onLinkClickHandler( e ){
		var currentHREF = $(this).attr('href');
		var pathname = window.location.hostname;
        // Interpolation magic to simplify Regex
		var matchExp = $$('/$1|$2|$3/', pathname, pathname.replace("www.",""), "#");
		console.log(matchExp);
		if ( !currentHREF.match(matchExp) ) { 
			gtag('event', 'Click', {
			  'event_category': 'Outbound',
			  'event_label': currentHREF
			});
		}
		//return false;
	}	
});
</script>
/** *******************************************
* Name: Campaign Tracker
* Date modified: 10/17/2013
* Description: The purpose of this campaign tracker is to 
* source how users are arriving at the donations page. 
* Instead of sitting around and creating a million custom
* campaign trackers, we are going to source traffic by URL. 
* 
* Here's the breakdown:
*  utm_source   = URL of the web page
*  utm_medium   = Device type (mobile vs. desktop)
*  utm_content  = browser name (IE, Firefox, Safari, Chrome)
*  utm_campaign = Campaign name (donate). Since we can track 
*                the dates of our radio campaigns + e-newsblasts, etc.,
*                there's no need to spell out a specific name campaign.
* 
** /

/**************************
Stop <a href /> from linking
**************************/
function stopEvent( e ){
	e = e || window.event;
	if( e ){
		if( e.preventDefault ){
			e.preventDefault();
		} else {
			e.returnValue = false;
		}
	}
}

function replaceSlash(url){     
    return url.replace(/\/$/, "");
}

/**************************
Get Browser Name
**************************/
function getBrowserName(){
    // !!! Requires jQuery 1.9.0 or below.
	//Differentiate between Safari and Chrome (webkit based)
	$.browser.chrome = $.browser.webkit && !!window.chrome;
	$.browser.safari = $.browser.webkit && !window.chrome;

	var name = "";
	if( $.browser.safari )  name = "Safari"
	if ($.browser.msie )    name = "Internet Explorer";
	if ($.browser.mozilla ) name = "Firefox";
	if ($.browser.chrome )  name = "Chrome";
	return name;
}

/**************************
Are users on mobile or desktop browser?
**************************/
function getDeviceType(){
	var isMobile = {
		Android: function() {
			return navigator.userAgent.match(/Android/i);
		},
		BlackBerry: function() {
			return navigator.userAgent.match(/BlackBerry/i);
		},
		iOS: function() {
			return navigator.userAgent.match(/iPhone|iPad|iPod/i);
		},
		Opera: function() {
			return navigator.userAgent.match(/Opera Mini/i);
		},
		Windows: function() {
			return navigator.userAgent.match(/IEisMobile/i);
		},
		any: function() {
			return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
		}
	};
	//Make the device names look pretty
	if( $.browser.device ){
		$.browser.device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
		return isMobile.any().toString();
	}
	//If no device, assume it's a desktop browser
	else {
		return "desktop";
	}
}

/**************************
Campaign URL construction
**************************/
function getCampaignURL( url, source, calltoaction ){
	url += "?";
	
	var params = {};
	params.utm_source   = source
	params.utm_medium   = getDeviceType()
	params.utm_content  = getBrowserName()
	params.utm_campaign = "donate"
	//params.cache_clear  =  new Date().getTime()
	if( calltoaction ) {
		//There's more than just a blank string
		if( calltoaction.length > 0 ){
			params.call_to_action = $.trim( calltoaction );			
		}		
	}

	$.each( params, function( n, value){
		var param =  n + "=" + value + "&";
		url += param;
	});
	
	return url.toLowerCase();
}

function scanLinks(){
	$.each( $("a"), function(key, value){
		//Get the current URL of the <a href=""> tag
		var currentURL = $(this).attr('href');
		//Search for this string expression
		var regexp = /http:\/\/mydomain.com\/mypath/;
		var pathname = window.location.pathname;
		//If any of the links match, continue forward
		if( currentURL.match( regexp ) ) {
			var newURL       = "http://mydomain.com/mypath";
			var id           = $(this).parent().parent().attr("id");
			var calltoaction = $(this).text();

			//Source as "index"
			if( pathname == "/" ) pathname = "index";
			
			//Source as "widget"
			if( id == "my_div_id" ) newURL = getCampaignURL( newURL, "widget" );
			//Source as pathname
			else newURL = getCampaignURL( newURL, replaceSlash(pathname), calltoaction );
			
			//console.log( newURL );
			//Apply new URL to existing <a href="" />
			$(this).attr('href', newURL );
		}
	});
}
//Scan links for Donation call outs
scanLinks();