55 * Licensed under the MIT and GPL licenses.
66 */
77
8+ /* Universal module definition */
9+
810( function ( factory ) {
911 if ( typeof define === 'function' && define . amd ) {
1012 // AMD
1113 define ( [ 'jquery' ] , factory ) ;
1214 } else if ( typeof module === 'object' && module . exports ) {
13- // Node/CommonJS
14- module . exports = function ( root , jQuery ) {
15- if ( jQuery === undefined ) {
16- if ( typeof window !== 'undefined' ) {
17- jQuery = require ( 'jquery' ) ;
18- }
19- else {
20- jQuery = require ( 'jquery' ) ( root ) ;
21- }
22- }
23- factory ( jQuery ) ;
24- return jQuery ;
25- } ;
15+ // CommonJS
16+ module . exports = factory ( require ( 'jquery' ) ) ;
2617 } else {
2718 // Browser globals
2819 factory ( jQuery ) ;
2920 }
3021} ( function ( $ ) {
31-
22+
23+ /* Scroll Depth */
24+
3225 "use strict" ;
33-
26+
3427 var defaults = {
3528 minHeight : 0 ,
3629 elements : [ ] ,
4134 gaGlobal : false ,
4235 gtmOverride : false
4336 } ;
44-
37+
4538 var $window = $ ( window ) ,
4639 cache = [ ] ,
4740 scrollEventBound = false ,
5043 classicGA ,
5144 gaGlobal ,
5245 standardEventHandler ;
53-
46+
5447 /*
5548 * Plugin
5649 */
57-
50+
5851 $ . scrollDepth = function ( options ) {
59-
52+
6053 var startTime = + new Date ;
61-
54+
6255 options = $ . extend ( { } , defaults , options ) ;
63-
56+
6457 // Return early if document height is too small
6558 if ( $ ( document ) . height ( ) < options . minHeight ) {
6659 return ;
6760 }
68-
61+
6962 /*
7063 * Determine which version of GA is being used
7164 * "ga", "__gaTracker", _gaq", and "dataLayer" are the possible globals
7265 */
73-
66+
7467 if ( options . gaGlobal ) {
7568 universalGA = true ;
7669 gaGlobal = options . gaGlobal ;
8174 universalGA = true ;
8275 gaGlobal = '__gaTracker' ;
8376 }
84-
77+
8578 if ( typeof _gaq !== "undefined" && typeof _gaq . push === "function" ) {
8679 classicGA = true ;
8780 }
88-
81+
8982 if ( typeof options . eventHandler === "function" ) {
9083 standardEventHandler = options . eventHandler ;
9184 } else if ( typeof dataLayer !== "undefined" && typeof dataLayer . push === "function" && ! options . gtmOverride ) {
92-
85+
9386 standardEventHandler = function ( data ) {
9487 dataLayer . push ( data ) ;
9588 } ;
9689 }
97-
90+
9891 /*
9992 * Functions
10093 */
101-
94+
10295 function sendEvent ( action , label , scrollDistance , timing ) {
103-
96+
10497 if ( standardEventHandler ) {
105-
98+
10699 standardEventHandler ( { 'event' : 'ScrollDistance' , 'eventCategory' : 'Scroll Depth' , 'eventAction' : action , 'eventLabel' : label , 'eventValue' : 1 , 'eventNonInteraction' : options . nonInteraction } ) ;
107-
100+
108101 if ( options . pixelDepth && arguments . length > 2 && scrollDistance > lastPixelDepth ) {
109102 lastPixelDepth = scrollDistance ;
110103 standardEventHandler ( { 'event' : 'ScrollDistance' , 'eventCategory' : 'Scroll Depth' , 'eventAction' : 'Pixel Depth' , 'eventLabel' : rounded ( scrollDistance ) , 'eventValue' : 1 , 'eventNonInteraction' : options . nonInteraction } ) ;
111104 }
112-
105+
113106 if ( options . userTiming && arguments . length > 3 ) {
114107 standardEventHandler ( { 'event' : 'ScrollTiming' , 'eventCategory' : 'Scroll Depth' , 'eventAction' : action , 'eventLabel' : label , 'eventTiming' : timing } ) ;
115108 }
116-
109+
117110 } else {
118-
111+
119112 if ( universalGA ) {
120-
113+
121114 window [ gaGlobal ] ( 'send' , 'event' , 'Scroll Depth' , action , label , 1 , { 'nonInteraction' : options . nonInteraction } ) ;
122-
115+
123116 if ( options . pixelDepth && arguments . length > 2 && scrollDistance > lastPixelDepth ) {
124117 lastPixelDepth = scrollDistance ;
125118 window [ gaGlobal ] ( 'send' , 'event' , 'Scroll Depth' , 'Pixel Depth' , rounded ( scrollDistance ) , 1 , { 'nonInteraction' : options . nonInteraction } ) ;
126119 }
127-
120+
128121 if ( options . userTiming && arguments . length > 3 ) {
129122 window [ gaGlobal ] ( 'send' , 'timing' , 'Scroll Depth' , action , timing , label ) ;
130123 }
131-
124+
132125 }
133-
126+
134127 if ( classicGA ) {
135-
128+
136129 _gaq . push ( [ '_trackEvent' , 'Scroll Depth' , action , label , 1 , options . nonInteraction ] ) ;
137-
130+
138131 if ( options . pixelDepth && arguments . length > 2 && scrollDistance > lastPixelDepth ) {
139132 lastPixelDepth = scrollDistance ;
140133 _gaq . push ( [ '_trackEvent' , 'Scroll Depth' , 'Pixel Depth' , rounded ( scrollDistance ) , 1 , options . nonInteraction ] ) ;
141134 }
142-
135+
143136 if ( options . userTiming && arguments . length > 3 ) {
144137 _gaq . push ( [ '_trackTiming' , 'Scroll Depth' , action , timing , label , 100 ] ) ;
145138 }
146-
139+
147140 }
148-
141+
149142 }
150-
143+
151144 }
152-
145+
153146 function calculateMarks ( docHeight ) {
154147 return {
155148 '25%' : parseInt ( docHeight * 0.25 , 10 ) ,
159152 '100%' : docHeight - 5
160153 } ;
161154 }
162-
155+
163156 function checkMarks ( marks , scrollDistance , timing ) {
164157 // Check each active mark
165158 $ . each ( marks , function ( key , val ) {
169162 }
170163 } ) ;
171164 }
172-
165+
173166 function checkElements ( elements , scrollDistance , timing ) {
174167 $ . each ( elements , function ( index , elem ) {
175168 if ( $ . inArray ( elem , cache ) === - 1 && $ ( elem ) . length ) {
180173 }
181174 } ) ;
182175 }
183-
176+
184177 function rounded ( scrollDistance ) {
185178 // Returns String
186179 return ( Math . floor ( scrollDistance / 250 ) * 250 ) . toString ( ) ;
187180 }
188-
181+
189182 function init ( ) {
190183 bindScrollDepth ( ) ;
191184 }
192-
185+
193186 /*
194187 * Public Methods
195188 */
196-
189+
197190 // Reset Scroll Depth with the originally initialized options
198191 $ . scrollDepth . reset = function ( ) {
199192 cache = [ ] ;
200193 lastPixelDepth = 0 ;
201194 $window . off ( 'scroll.scrollDepth' ) ;
202195 bindScrollDepth ( ) ;
203196 } ;
204-
197+
205198 // Add DOM elements to be tracked
206199 $ . scrollDepth . addElements = function ( elems ) {
207-
200+
208201 if ( typeof elems == "undefined" || ! $ . isArray ( elems ) ) {
209202 return ;
210203 }
211-
204+
212205 $ . merge ( options . elements , elems ) ;
213-
206+
214207 // If scroll event has been unbound from window, rebind
215208 if ( ! scrollEventBound ) {
216209 bindScrollDepth ( ) ;
217210 }
218-
211+
219212 } ;
220-
213+
221214 // Remove DOM elements currently tracked
222215 $ . scrollDepth . removeElements = function ( elems ) {
223-
216+
224217 if ( typeof elems == "undefined" || ! $ . isArray ( elems ) ) {
225218 return ;
226219 }
227-
220+
228221 $ . each ( elems , function ( index , elem ) {
229-
222+
230223 var inElementsArray = $ . inArray ( elem , options . elements ) ;
231224 var inCacheArray = $ . inArray ( elem , cache ) ;
232-
225+
233226 if ( inElementsArray != - 1 ) {
234227 options . elements . splice ( inElementsArray , 1 ) ;
235228 }
236-
229+
237230 if ( inCacheArray != - 1 ) {
238231 cache . splice ( inCacheArray , 1 ) ;
239232 }
240-
233+
241234 } ) ;
242-
235+
243236 } ;
244-
237+
245238 /*
246239 * Throttle function borrowed from:
247240 * Underscore.js 1.5.2
248241 * http://underscorejs.org
249242 * (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
250243 * Underscore may be freely distributed under the MIT license.
251244 */
252-
245+
253246 function throttle ( func , wait ) {
254247 var context , args , result ;
255248 var timeout = null ;
276269 return result ;
277270 } ;
278271 }
279-
272+
280273 /*
281274 * Scroll Event
282275 */
283-
276+
284277 function bindScrollDepth ( ) {
285-
278+
286279 scrollEventBound = true ;
287-
280+
288281 $window . on ( 'scroll.scrollDepth' , throttle ( function ( ) {
289282 /*
290283 * We calculate document and window height on each scroll event to
291284 * account for dynamic DOM changes.
292285 */
293-
286+
294287 var docHeight = $ ( document ) . height ( ) ,
295288 winHeight = window . innerHeight ? window . innerHeight : $window . height ( ) ,
296289 scrollDistance = $window . scrollTop ( ) + winHeight ,
297-
290+
298291 // Recalculate percentage marks
299292 marks = calculateMarks ( docHeight ) ,
300-
293+
301294 // Timing
302295 timing = + new Date - startTime ;
303-
296+
304297 // If all marks already hit, unbind scroll event
305298 if ( cache . length >= options . elements . length + ( options . percentage ? 4 :0 ) ) {
306299 $window . off ( 'scroll.scrollDepth' ) ;
307300 scrollEventBound = false ;
308301 return ;
309302 }
310-
303+
311304 // Check specified DOM elements
312305 if ( options . elements ) {
313306 checkElements ( options . elements , scrollDistance , timing ) ;
314307 }
315-
308+
316309 // Check standard marks
317310 if ( options . percentage ) {
318311 checkMarks ( marks , scrollDistance , timing ) ;
319312 }
320313 } , 500 ) ) ;
321-
314+
322315 }
323-
316+
324317 init ( ) ;
325-
318+
326319 } ;
327-
320+
328321} ) ) ;
0 commit comments