forked from robflaherty/scroll-depth
-
Notifications
You must be signed in to change notification settings - Fork 0
/
jquery.scrolldepth.js
120 lines (96 loc) · 2.89 KB
/
jquery.scrolldepth.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*!
* jquery.scrolldepth.js | v0.1.1
* Copyright (c) 2012 Rob Flaherty (@robflaherty)
* Licensed under the MIT and GPL licenses.
*/
;(function ( $, window, document, undefined ) {
"use strict";
var defaults = {
elements: [],
minHeight: 0,
offset: 0, // Not used yet
percentage: true,
testing: false
},
$window = $(window),
cache = [];
/*
* Plugin
*/
$.scrollDepth = function(options) {
options = $.extend({}, defaults, options);
// Return early if document height is too small
if ( $(document).height() < options.minHeight ) {
return;
}
// Establish baseline (0% scroll)
sendEvent('Percentage', 'Baseline');
/*
* Functions
*/
function sendEvent(action, label) {
if (!options.testing) {
_gaq.push(['_trackEvent', 'Scroll Depth', action, label, 1, true]);
} else {
$('#console').html(action + ': ' + label);
}
}
function calculateMarks(docHeight) {
return {
'25%' : parseInt(docHeight * 0.25, 10),
'50%' : parseInt(docHeight * 0.50, 10),
'75%' : parseInt(docHeight * 0.75, 10),
// 1px cushion to trigger 100% event in iOS
'100%': docHeight - 1
};
}
function checkMarks(marks, scrollDistance) {
// Check each active mark
$.each(marks, function(key, val) {
if ( $.inArray(key, cache) === -1 && scrollDistance >= val ) {
sendEvent('Percentage', key);
cache.push(key);
}
});
}
function checkElements(elements, scrollDistance) {
$.each(elements, function(index, elem) {
if ( $.inArray(elem, cache) === -1 && $(elem).length ) {
if ( scrollDistance >= $(elem).offset().top ) {
sendEvent('Elements', elem);
cache.push(elem);
}
}
});
}
/*
* Scroll Event
*/
$window.on('scroll.scrollDepth', function() {
/*
* We calculate document and window height on each scroll event to
* account for dynamic DOM changes.
*/
var docHeight = $(document).height(),
winHeight = window.innerHeight ? window.innerHeight : $window.height(),
scrollDistance = $window.scrollTop() + winHeight,
// Offset not being used yet
offset = parseInt(winHeight * (options.offset / 100), 10),
// Recalculate percentage marks
marks = calculateMarks(docHeight);
// If all marks already hit, unbind scroll event
if (cache.length >= 4 + options.elements.length) {
$window.off('scroll.scrollDepth');
return;
}
// Check specified DOM elements
if (options.elements) {
checkElements(options.elements, scrollDistance);
}
// Check standard marks
if (options.percentage) {
checkMarks(marks, scrollDistance);
}
});
};
})( jQuery, window, document );