Shoora
4/29/2019 - 2:13 PM

Google Analytics Enhanced

Google Analytics Enhanced

/**
	Table of Contents: Analytics
	============================

	1.0 - Functions
	2.0 - Processing

**/

/* globals consoleMessage, ga, ready, forEachElement, checkForParent */

/*--------------------------------------------------------------
1.0 - Functions
--------------------------------------------------------------*/

/**
 * Send analytics data for tracking.
 *
 * @param {url.string} the url to send to analytics
 * @param {category.string} the category variable to send
 * @param {action.string} the action variable to send
 * @param {label.string} the label variable to send
 *
 */
function sendAnalytics(category, action, label, url, value) {

	'use strict';

	// Category default.
	if ( category === null || category === undefined ) {
		category = 'link';
	}

	// Action default.
	if ( action === null || action === undefined ) {
		action = 'click';
	}

	// Label default.
	if ( label === null || label === undefined ) {
		if ( url.indexOf('#') === 0 ) {
			label = 'Anchor Link';
		} else {
			label = 'Content Link';
		}
	}

	// URL default.
	if ( url === null || url === undefined ) {
		url = 'non link';
	}

	// Set other GA functions [cough] YOAST! [cough].
	if ( typeof __gaTracker == 'function' ) {
		__gaTracker( function() {
			window.ga = __gaTracker;
		});
	}

	// Send to analytics.
	if ( typeof ga == 'function' ) {

		if ( value === undefined || value === null ) {

			// Report the data sent to analytics.
			if ( typeof consoleMessage == 'function' ) {
				consoleMessage('info', 'ga send: [event], ['+ category +'], ['+ action +'], ['+ label +' ('+ url +')]');
			}

			// Send to analytics.
			ga('send', 'event', category, action, label + ': ' + url);

		} else {

			// Report the data sent to analytics.
			if ( typeof consoleMessage == 'function' ) {
				consoleMessage('info', 'ga send: [event], ['+ category +'], ['+ action +'], ['+ label +' ('+ url +')], ['+ value +']');
			}

			// Send to analytics.
			ga('send', 'event', category, action, label + ': ' + url, value);

		}
	} else {
		return false;
	}
}

/**
 * Send analytics when the user reaches the bottom of
 * the page - only once.
 *
 * @param {markerID.string} the ID of the elment at the bottom to test (footer, site credit, ets)
 */
function getToTheBottom(markerId) {

	'use strict';

	// Set default bottom test to false.
	var scrolledToBottom = false;


	function hitBottom() {

		var body = document.body,
			scroll = body.scrollTop,

			// Get the id of the markerId.
			bottomMarker = document.getElementById(markerId),

			// Get the bounding rectangle and it's top position.
			rect = bottomMarker.getBoundingClientRect(),
			top = rect.top + scroll,

			// Get the coordinates of the bottom minus 50px.
			nearBottom = top - 50 - window.innerHeight;

		// If we srolled near the bottom.
		if ( scroll > nearBottom && !scrolledToBottom ) {

			// Send to analytics.
			if ( typeof sendAnalytics == 'function') {
				sendAnalytics('scroll', 'bottom', 'Scrolled to Bottom');
			}

			/**
			 * Set the bottom test to true so we don't keep
			 * sending the analytic variable. Only prosess once.
			 */

			scrolledToBottom = true;
		}
	}

	window.onscroll = function(){

		hitBottom();

	};

	window.onresize = function() {

		hitBottom();
	};
}


/**
 * Attach listener to all <a> elements to gather data analytics and send.
 * Set as function to call after user interaction items.
 *
 * @param {conainer.string} Element to target for {selector} children
 */

function linkListenAnalytics(container) {

	'use strict';

	// For every link.
	forEachElement(container,'a', function(el){


		// Add a listenter for the click.
		el.addEventListener('click', function(event){

			// Don't use the link just yet.
			event.preventDefault();

			// Get the data attributes.
			var aCategory = el.getAttribute('data-analytics-category'),
				aAction = el.getAttribute('data-analytics-action'),
				aLabel = el.getAttribute('data-analytics-label'),
				aURL = el.getAttribute('href'),
				aTarget = el.getAttribute('target');

			// Check for the click type.
			if ( event.metaKey || event.ctrlKey || event.which == 2 ) {
				aTarget = '_blank';
			}

			// Set the label to the content html if empty.
			if ( aLabel === null ) {
				aLabel = el.innerHTML;
			}

			// Set the Category.
			if ( !aCategory ) {

				// Default is link item.
				aCategory = 'link';

				// Check if we have a list item.
				var isListItem = checkForParent(el, 'LI');

				if ( isListItem ) {

					// Check if the link is part of a menu or sub-menu.
					var isMenuItem = el.parentNode.classList.contains('menu-item'),
						isSubMenuItem = el.parentNode.parentNode.classList.contains('sub-menu');

					// Check if the list item is part of a nav, sub menu, or default to list item.
					aCategory = 'list item';

					if ( isMenuItem ) {
						aCategory = 'menu';
					}

					if ( isSubMenuItem ) {
						aCategory = 'sub menu';
					}
				}

			}

			// If the link is not a nav button.
			if ( !el.classList.contains('nav-button')  && !el.classList.contains('button-popular-links') ) {
				sendAnalytics(aCategory, aAction, aLabel, aURL);
			}

			// Check if we have a click time set.
			if ( typeof( clickTime ) !== 'undefined') {
				clearTimeout(clickTime);
			}

			// After a timeout, go to the intended link.
			var clickTime = setTimeout( function() {

				// If you disabale this - the mobile menu will not work.

				// No target link.
				if ( aTarget === undefined || aTarget === null || aTarget != '_blank' ) {

					// Comment out for testing.
					document.location.href = aURL;

				}

				// Target link.
				else {

					// Comment out for testing.
					window.open( aURL, aTarget );

				}

			}, 200);

		});

	});
}


/**
 * Capture the input for search and pass to analytics.
 *
 * @return  {void}
 */
function searchAnalytics() {

	'use strict';

	// Get the class.
	var searchForm = '.search-form';

	forEachElement(null, searchForm, function(el) {

		// Listen for the search form to be submitted.
		el.addEventListener('submit', function(event){

			// Don't process the form yet.
			event.preventDefault();

			// Get the search input and it's value.
			var searchValue = el.querySelector('.search-field').value;

			// If sendAnalytics exist - send the value to analytics.
			if ( typeof sendAnalytics == 'function' ) {
				sendAnalytics('search', 'submit', 'Search Term', searchValue);
			}

			// Check if we have a click time set.
			if ( typeof( searchTime ) !== 'undefined') {
				clearTimeout(searchTime);
			}

			// After a timeout, go to the intended link.
			var searchTime = setTimeout( function() {

				// .2s delay to allow the form to be tracked.
				el.submit();

			}, 200);
		});
	});
}


/*--------------------------------------------------------------
2.0 - Processing
--------------------------------------------------------------*/

// When the document is loaded and ready.
ready(function(){

	'use strict';

	var wrapper = document.getElementById('site-outer-wrapper');

	// Set listener for <a> tag links.
	linkListenAnalytics(wrapper);

	// Search analytics.
	searchAnalytics();

	// Reached the bottom of the page.
	getToTheBottom('analytics-bottom-tracker');

});