Skip to content

Instantly share code, notes, and snippets.

@coldnew
Forked from igrigorik/analytics.patch
Last active August 29, 2015 14:16
Show Gist options
  • Save coldnew/a1762dfc0a7a83ef4d59 to your computer and use it in GitHub Desktop.
Save coldnew/a1762dfc0a7a83ef4d59 to your computer and use it in GitHub Desktop.
From 4a3bb99fe5eecd06e77f4fedb5729466df09750f Mon Sep 17 00:00:00 2001
From: Ilya Grigorik <[email protected]>
Date: Fri, 18 May 2012 06:41:34 +0800
Subject: [PATCH] add outbound click tracking + time on slide analytics
plugins for GA
---
js/analytics/outbound-clicks.js | 102 +++++++++++++++++++++++++++++++++++++++
js/analytics/time-on-slide.js | 25 ++++++++++
js/slide-deck.js | 5 ++
3 files changed, 132 insertions(+), 0 deletions(-)
create mode 100644 js/analytics/outbound-clicks.js
create mode 100644 js/analytics/time-on-slide.js
diff --git a/js/analytics/outbound-clicks.js b/js/analytics/outbound-clicks.js
new file mode 100644
index 0000000..950cd7b
--- /dev/null
+++ b/js/analytics/outbound-clicks.js
@@ -0,0 +1,102 @@
+/**
+ * A little script to handle outbound link tracking in Google Anlaytics.
+ * Links are tracked as events.
+ * @author nickski15@ (Nick Mihailovski)
+ */
+
+// Namespace.
+var _gaq = _gaq || [];
+
+function trackOutboundLinks(options) {
+ return function() {
+ var debug = options.debug || false;
+ var element = options.element || document;
+ var eventName = options.eventName || 'click';
+
+ var traverseDepth = 1;
+ var anchorUrl = '';
+ var anchorTarget = '';
+ var cleanUrl = '';
+
+ if (element.addEventListener) {
+ element.addEventListener(eventName, checkEvent);
+ } else {
+ element.attachEvent('on' + eventName, checkEvent);
+ }
+
+ function checkEvent(event) {
+ var event = event || window.event;
+ var targetElement = event.target || event.srcElement;
+
+ var anchor = getParentAnchor(targetElement, traverseDepth);
+ if (anchor && isOutbound(anchor)) {
+
+ // prevent default behavior.
+ if (event.preventDefault) {
+ event.preventDefault();
+ } else {
+ event.returnValue = false;
+ }
+ anchorUrl = anchor.href;
+ anchorTarget = anchor.target;
+
+ track();
+ }
+ };
+
+ function getParentAnchor(targetElement, depth) {
+ if (targetElement.tagName == 'A') {
+ return targetElement;
+ } else if (targetElement.tagName == 'BODY' || depth < 0) {
+ return;
+ } else {
+ targetElement = targetElement.parentNode;
+ return getParentAnchor(targetElement, --depth);
+ }
+ }
+
+ function isOutbound(anchor) {
+ var anchorParts = anchor.href.split('//');
+
+ // "//" must be present to continue.
+ if (anchorParts.length < 2) {
+ return false;
+ }
+ cleanUrl = anchorParts[1];
+
+ // Remove port, then remove path.
+ var hostname = cleanUrl.split(':')[0].split('/')[0];
+ if (document.location.hostname != hostname) {
+ return true;
+ }
+ return false;
+ }
+
+ function track() {
+ window._gaq.push(['_set', {'hitCallback': hitCallback}]);
+ var command = ['_trackEvent', 'outboundLink', cleanUrl];
+ if (debug) {
+ console.log(command);
+ } else {
+ window._gaq.push(command);
+ }
+ }
+
+ function hitCallback() {
+ if (debug) {
+ return;
+ }
+ if (anchorTarget == '_blank') {
+ window.open(anchorUrl);
+ } else if (anchorTarget == '_top') {
+ window.top.location = anchorUrl;
+ } else if (anchorTarget == '_parent') {
+ window.parent.location = anchorUrl;
+ }
+ // If no target or _self.
+ window.location = anchorUrl;
+ }
+ }
+};
+
+_gaq.push(trackOutboundLinks({'debug': false}));
\ No newline at end of file
diff --git a/js/analytics/time-on-slide.js b/js/analytics/time-on-slide.js
new file mode 100644
index 0000000..66c62df
--- /dev/null
+++ b/js/analytics/time-on-slide.js
@@ -0,0 +1,25 @@
+/**
+ * Simple analytics plugin to track time on slide (via user timings).
+ * To view the reports: Content > Site Speed > User Timings
+ * @author: igrigorik (Ilya Grigorik)
+ */
+
+var slideStartTime = new Date(),
+ oldSlideNum = window.slidedeck.curSlide_ + 1,
+ timeOnSlide;
+
+document.addEventListener('slideenter', function(e) {
+ timeOnSlide = new Date() - slideStartTime;
+ slideStartTime = new Date();
+
+ if (document.location.hostname == 'localhost') {
+ console.log('slide enter: ' + e.slideNumber + ", was on slide: " + oldSlideNum + ", time: " + timeOnSlide);
+ } else {
+ // filter out transitions under 2s and over 20 minutes
+ if (timeOnSlide >= 2000 && timeOnSlide <= 120000) {
+ _gaq.push(['_trackTiming', 'slide', String(oldSlide), timeOnSlide, 'slide ' + oldSlide, 100]);
+ }
+ }
+
+ oldSlideNum = window.slidedeck.curSlide_ + 1;
+}, false);
\ No newline at end of file
diff --git a/js/slide-deck.js b/js/slide-deck.js
index 696767e..94be785 100644
--- a/js/slide-deck.js
+++ b/js/slide-deck.js
@@ -737,6 +737,11 @@ SlideDeck.prototype.loadAnalytics_ = function() {
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);
})();
+
+ // load analytics plugins
+ Modernizr.load({
+ load: ['js/analytics/time-on-slide.js', 'js/analytics/outbound-clicks.js']
+ })
};
--
1.7.7.5 (Apple Git-26)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment