PageSourceSearch

https://www.keytofashion.com/wp-content/themes/applique/assets/js/jquery.scrolldepth.js

js keytofashion.com collected 2026-09-29 09:25:22 UTC 8,776 bytes, 305 lines download raw bytes

vendor: 8,776 bytes, lines 1-305
1/*!
2 * @preserve
3 * jquery.scrolldepth.js | v0.9
4 * Copyright (c) 2015 Rob Flaherty (@robflaherty)
5 * Licensed under the MIT and GPL licenses.
6 */
7;(function ( $, window, document, undefined ) {
8
9  "use strict";
10
11  var defaults = {
12    minHeight: 0,
13    elements: [],
14    percentage: true,
15    userTiming: true,
16    pixelDepth: true,
17    nonInteraction: true,
18    gaGlobal: false,
19    gtmOverride: false
20  };
21
22  var $window = $(window),
23    cache = [],
24    scrollEventBound = false,
25    lastPixelDepth = 0,
26    universalGA,
27    classicGA,
28    gaGlobal,
29    standardEventHandler;
30
31  /*
32   * Plugin
33   */
34
35  $.scrollDepth = function(options) {
36
37    var startTime = +new Date;
38
39    options = $.extend({}, defaults, options);
40
41    // Return early if document height is too small
42    if ( $(document).height() < options.minHeight ) {
43      return;
44    }
45
46    /*
47     * Determine which version of GA is being used
48     * "ga", "__gaTracker", _gaq", and "dataLayer" are the possible globals
49     */
50
51    if (options.gaGlobal) {
52      universalGA = true;
53      gaGlobal = options.gaGlobal;
54    } else if (typeof ga === "function") {
55      universalGA = true;
56      gaGlobal = 'ga';
57    } else if (typeof __gaTracker === "function") {
58      universalGA = true;
59      gaGlobal = '__gaTracker';
60    }
61
62    if (typeof _gaq !== "undefined" && typeof _gaq.push === "function") {
63      classicGA = true;
64    }
65
66    if (typeof options.eventHandler === "function") {
67      standardEventHandler = options.eventHandler;
68    } else if (typeof dataLayer !== "undefined" && typeof dataLayer.push === "function" && !options.gtmOverride) {
69
70      standardEventHandler = function(data) {
71        dataLayer.push(data);
72      };
73    }
74
75    /*
76     * Functions
77     */
78
79    function sendEvent(action, label, scrollDistance, timing) {
80
81      if (standardEventHandler) {
82
83        standardEventHandler({'event': 'ScrollDistance', 'eventCategory': 'Scroll Depth', 'eventAction': action, 'eventLabel': label, 'eventValue': 1, 'eventNonInteraction': options.nonInteraction});
84
85        if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) {
86          lastPixelDepth = scrollDistance;
87          standardEventHandler({'event': 'ScrollDistance', 'eventCategory': 'Scroll Depth', 'eventAction': 'Pixel Depth', 'eventLabel': rounded(scrollDistance), 'eventValue': 1, 'eventNonInteraction': options.nonInteraction});
88        }
89
90        if (options.userTiming && arguments.length > 3) {
91          standardEventHandler({'event': 'ScrollTiming', 'eventCategory': 'Scroll Depth', 'eventAction': action, 'eventLabel': label, 'eventTiming': timing});
92        }
93
94      } else {
95
96        if (universalGA) {
97
98          window[gaGlobal]('send', 'event', 'Scroll Depth', action, label, 1, {'nonInteraction': options.nonInteraction});
99
100          if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) {
101            lastPixelDepth = scrollDistance;
102            window[gaGlobal]('send', 'event', 'Scroll Depth', 'Pixel Depth', rounded(scrollDistance), 1, {'nonInteraction': options.nonInteraction});
103          }
104
105          if (options.userTiming && arguments.length > 3) {
106            window[gaGlobal]('send', 'timing', 'Scroll Depth', action, timing, label);
107          }
108
109        }
110
111        if (classicGA) {
112
113          _gaq.push(['_trackEvent', 'Scroll Depth', action, label, 1, options.nonInteraction]);
114
115          if (options.pixelDepth && arguments.length > 2 && scrollDistance > lastPixelDepth) {
116            lastPixelDepth = scrollDistance;
117            _gaq.push(['_trackEvent', 'Scroll Depth', 'Pixel Depth', rounded(scrollDistance), 1, options.nonInteraction]);
118          }
119
120          if (options.userTiming && arguments.length > 3) {
121            _gaq.push(['_trackTiming', 'Scroll Depth', action, timing, label, 100]);
122          }
123
124        }
125
126      }
127
128    }
129
130    function calculateMarks(docHeight) {
131      return {
132        '25%' : parseInt(docHeight * 0.25, 10),
133        '50%' : parseInt(docHeight * 0.50, 10),
134        '75%' : parseInt(docHeight * 0.75, 10),
135        // Cushion to trigger 100% event in iOS
136        '100%': docHeight - 5
137      };
138    }
139
140    function checkMarks(marks, scrollDistance, timing) {
141      // Check each active mark
142      $.each(marks, function(key, val) {
143        if ( $.inArray(key, cache) === -1 && scrollDistance >= val ) {
144          sendEvent('Percentage', key, scrollDistance, timing);
145          cache.push(key);
146        }
147      });
148    }
149
150    function checkElements(elements, scrollDistance, timing) {
151      $.each(elements, function(index, elem) {
152        if ( $.inArray(elem, cache) === -1 && $(elem).length ) {
153          if ( scrollDistance >= $(elem).offset().top ) {
154            sendEvent('Elements', elem, scrollDistance, timing);
155            cache.push(elem);
156          }
157        }
158      });
159    }
160
161    function rounded(scrollDistance) {
162      // Returns String
163      return (Math.floor(scrollDistance/250) * 250).toString();
164    }
165
166    function init() {
167      bindScrollDepth();
168    }
169
170    /*
171     * Public Methods
172     */
173
174    // Reset Scroll Depth with the originally initialized options
175    $.scrollDepth.reset = function() {
176      cache = [];
177      lastPixelDepth = 0;
178      $window.off('scroll.scrollDepth');
179      bindScrollDepth();
180    };
181
182    // Add DOM elements to be tracked
183    $.scrollDepth.addElements = function(elems) {
184
185      if (typeof elems == "undefined" || !$.isArray(elems)) {
186        return;
187      }
188
189      $.merge(options.elements, elems);
190
191      // If scroll event has been unbound from window, rebind
192      if (!scrollEventBound) {
193        bindScrollDepth();
194      }
195
196    };
197
198    // Remove DOM elements currently tracked
199    $.scrollDepth.removeElements = function(elems) {
200
201      if (typeof elems == "undefined" || !$.isArray(elems)) {
202        return;
203      }
204
205      $.each(elems, function(index, elem) {
206
207        var inElementsArray = $.inArray(elem, options.elements);
208        var inCacheArray = $.inArray(elem, cache);
209
210        if (inElementsArray != -1) {
211          options.elements.splice(inElementsArray, 1);
212        }
213
214        if (inCacheArray != -1) {
215          cache.splice(inCacheArray, 1);
216        }
217
218      });
219
220    };
221
222    /*
223     * Throttle function borrowed from:
224     * Underscore.js 1.5.2
225     * http://underscorejs.org
226     * (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
227     * Underscore may be freely distributed under the MIT license.
228     */
229
230    function throttle(func, wait) {
231      var context, args, result;
232      var timeout = null;
233      var previous = 0;
234      var later = function() {
235        previous = new Date;
236        timeout = null;
237        result = func.apply(context, args);
238      };
239      return function() {
240        var now = new Date;
241        if (!previous) previous = now;
242        var remaining = wait - (now - previous);
243        context = this;
244        args = arguments;
245        if (remaining <= 0) {
246          clearTimeout(timeout);
247          timeout = null;
248          previous = now;
249          result = func.apply(context, args);
250        } else if (!timeout) {
251          timeout = setTimeout(later, remaining);
252        }
253        return result;
254      };
255    }
256
257    /*
258     * Scroll Event
259     */
260
261    function bindScrollDepth() {
262
263      scrollEventBound = true;
264
265      $window.on('scroll.scrollDepth', throttle(function() {
266        /*
267         * We calculate document and window height on each scroll event to
268         * account for dynamic DOM changes.
269         */
270
271        var docHeight = $(document).height(),
272          winHeight = window.innerHeight ? window.innerHeight : $window.height(),
273          scrollDistance = $window.scrollTop() + winHeight,
274
275          // Recalculate percentage marks
276          marks = calculateMarks(docHeight),
277
278          // Timing
279          timing = +new Date - startTime;
280
281        // If all marks already hit, unbind scroll event
282        if (cache.length >= options.elements.length + (options.percentage ? 4:0)) {
283          $window.off('scroll.scrollDepth');
284          scrollEventBound = false;
285          return;
286        }
287
288        // Check specified DOM elements
289        if (options.elements) {
290          checkElements(options.elements, scrollDistance, timing);
291        }
292
293        // Check standard marks
294        if (options.percentage) {
295          checkMarks(marks, scrollDistance, timing);
296        }
297      }, 500));
298
299    }
300
301    init();
302
303  };
304
305})( jQuery, window, document );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.