|
5 | 5 | * Licensed under the MIT and GPL licenses.
|
6 | 6 | */
|
7 | 7 | ;(function ( $, window, document, undefined ) {
|
8 |
| - |
| 8 | + |
9 | 9 | "use strict";
|
10 | 10 |
|
11 | 11 | var defaults = {
|
12 |
| - elements: [], |
13 | 12 | minHeight: 0,
|
| 13 | + elements: [], |
14 | 14 | percentage: true,
|
15 |
| - userTiming: true |
16 |
| - }, |
| 15 | + userTiming: true, |
| 16 | + pixelDepth: true |
| 17 | + }; |
17 | 18 |
|
18 |
| - $window = $(window), |
19 |
| - cache = []; |
| 19 | + var $window = $(window), |
| 20 | + cache = [], |
| 21 | + lastPixelDepth = 0, |
| 22 | + universalGA, |
| 23 | + classicGA, |
| 24 | + googleTagManager; |
20 | 25 |
|
21 | 26 | /*
|
22 | 27 | * Plugin
|
23 | 28 | */
|
24 | 29 |
|
25 | 30 | $.scrollDepth = function(options) {
|
26 |
| - |
| 31 | + |
27 | 32 | var startTime = +new Date;
|
28 | 33 |
|
29 | 34 | options = $.extend({}, defaults, options);
|
|
33 | 38 | return;
|
34 | 39 | }
|
35 | 40 |
|
| 41 | + /* |
| 42 | + * Determine which version of GA is being used |
| 43 | + * "ga", "_gaq", and "dataLayer" are the possible globals |
| 44 | + */ |
| 45 | + |
| 46 | + if (typeof ga === "function") { |
| 47 | + universalGA = true; |
| 48 | + } |
| 49 | + |
| 50 | + if (typeof _gaq !== "undefined" && typeof _gaq.push === "function") { |
| 51 | + classicGA = true; |
| 52 | + } |
| 53 | + |
| 54 | + if (typeof dataLayer !== "undefined" && typeof dataLayer.push === "function") { |
| 55 | + googleTagManager = true; |
| 56 | + } |
| 57 | + |
36 | 58 | // Establish baseline (0% scroll)
|
37 | 59 | sendEvent('Percentage', 'Baseline');
|
38 | 60 |
|
39 | 61 | /*
|
40 | 62 | * Functions
|
41 | 63 | */
|
42 | 64 |
|
43 |
| - function sendEvent(action, label, timing) { |
| 65 | + function sendEvent(action, label, scrollDistance, timing) { |
44 | 66 |
|
45 |
| - if (typeof dataLayer !== "undefined" && typeof dataLayer.push === "function") { |
46 |
| - dataLayer.push({'event':'ScrollDistance', 'eventCategory':'Scroll Depth', 'eventAction': action, 'eventLabel': label, 'eventValue': 1, 'eventNonInteraction': true}); |
| 67 | + if (googleTagManager) { |
47 | 68 |
|
48 |
| - if (options.userTiming && arguments.length > 2) { |
49 |
| - dataLayer.push({'event':'ScrollTiming', 'eventCategory':'Scroll Depth', 'eventAction': action, 'eventLabel': label, 'eventTiming': timing}); |
50 |
| - } |
51 |
| - } else { |
| 69 | + dataLayer.push({'event': 'ScrollDistance', 'eventCategory': 'Scroll Depth', 'eventAction': action, 'eventLabel': label, 'eventValue': 1, 'eventNonInteraction': true}); |
| 70 | + |
| 71 | + if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) { |
| 72 | + lastPixelDepth = scrollDistance; |
| 73 | + dataLayer.push({'event': 'ScrollDistance', 'eventCategory': 'Scroll Depth', 'eventAction': 'Pixel Depth', 'eventLabel': scrollDistance.toString(), 'eventValue': 1, 'eventNonInteraction': true}); |
| 74 | + } |
| 75 | + |
| 76 | + if (options.userTiming && arguments.length > 3) { |
| 77 | + dataLayer.push({'event': 'ScrollTiming', 'eventCategory': 'Scroll Depth', 'eventAction': action, 'eventLabel': label, 'eventTiming': timing}); |
| 78 | + } |
| 79 | + |
| 80 | + } else { |
52 | 81 |
|
53 |
| - if (typeof ga === "function") { |
54 |
| - ga('send', 'event', 'Scroll Depth', action, label, 1, {'nonInteraction': 1}); |
| 82 | + if (universalGA) { |
55 | 83 |
|
56 |
| - if (options.userTiming && arguments.length > 2) { |
57 |
| - ga('send', 'timing', 'Scroll Depth', action, timing, label); |
58 |
| - } |
| 84 | + ga('send', 'event', 'Scroll Depth', action, label, 1, {'nonInteraction': 1}); |
| 85 | + |
| 86 | + if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) { |
| 87 | + lastPixelDepth = scrollDistance; |
| 88 | + ga('send', 'event', 'Scroll Depth', 'Pixel Depth', scrollDistance.toString(), 1, {'nonInteraction': 1}); |
| 89 | + } |
| 90 | + |
| 91 | + if (options.userTiming && arguments.length > 3) { |
| 92 | + ga('send', 'timing', 'Scroll Depth', action, timing, label); |
59 | 93 | }
|
60 | 94 |
|
61 |
| - if (typeof _gaq !== "undefined" && typeof _gaq.push === "function") { |
62 |
| - _gaq.push(['_trackEvent', 'Scroll Depth', action, label, 1, true]); |
| 95 | + } |
| 96 | + |
| 97 | + if (classicGA) { |
| 98 | + |
| 99 | + _gaq.push(['_trackEvent', 'Scroll Depth', action, label, 1, true]); |
| 100 | + |
| 101 | + if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) { |
| 102 | + lastPixelDepth = scrollDistance; |
| 103 | + _gaq.push(['_trackEvent', 'Scroll Depth', 'Pixel Depth', scrollDistance.toString(), 1, true]); |
| 104 | + } |
63 | 105 |
|
64 |
| - if (options.userTiming && arguments.length > 2) { |
65 |
| - _gaq.push(['_trackTiming', 'Scroll Depth', action, timing, label, 100]); |
66 |
| - } |
| 106 | + if (options.userTiming && arguments.length > 3) { |
| 107 | + _gaq.push(['_trackTiming', 'Scroll Depth', action, timing, label, 100]); |
67 | 108 | }
|
| 109 | + |
68 | 110 | }
|
| 111 | + |
| 112 | + } |
| 113 | + |
69 | 114 | }
|
70 | 115 |
|
71 | 116 | function calculateMarks(docHeight) {
|
|
82 | 127 | // Check each active mark
|
83 | 128 | $.each(marks, function(key, val) {
|
84 | 129 | if ( $.inArray(key, cache) === -1 && scrollDistance >= val ) {
|
85 |
| - sendEvent('Percentage', key, timing); |
| 130 | + sendEvent('Percentage', key, scrollDistance, timing); |
86 | 131 | cache.push(key);
|
87 | 132 | }
|
88 | 133 | });
|
|
92 | 137 | $.each(elements, function(index, elem) {
|
93 | 138 | if ( $.inArray(elem, cache) === -1 && $(elem).length ) {
|
94 | 139 | if ( scrollDistance >= $(elem).offset().top ) {
|
95 |
| - sendEvent('Elements', elem, timing); |
| 140 | + sendEvent('Elements', elem, scrollDistance, timing); |
96 | 141 | cache.push(elem);
|
97 | 142 | }
|
98 | 143 | }
|
|
166 | 211 | }
|
167 | 212 |
|
168 | 213 | // Check standard marks
|
169 |
| - if (options.percentage) { |
| 214 | + if (options.percentage) { |
170 | 215 | checkMarks(marks, scrollDistance, timing);
|
171 | 216 | }
|
172 | 217 | }, 500));
|
|
0 commit comments