forked from zuk/jquery.inview
-
Notifications
You must be signed in to change notification settings - Fork 483
/
Copy pathjquery.inview2.js
89 lines (79 loc) · 2.93 KB
/
jquery.inview2.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
/**
* Jquery Inview 2
* Version: 0.1
* Author: Matthew Frey (mmmeff)
* - forked from http://github.com/protonet/jquery.inview/
*/
(function ($) {
var inviewObjects = {},
d = document,
w = window,
documentElement = d.documentElement,
expando = $.expando,
timer,
// pixel count margins to wrap viewport (negative gives extra time for dom to render)
yMargin = -300,
xMargin = 0;
$.event.special.inview = {
add: function(data) {
inviewObjects[data.guid + "-" + this[expando]] = { data: data, $element: $(this) };
// Use setInterval in order to also make sure this captures elements within
// "overflow:scroll" elements or elements that appeared in the dom tree due to
// dom manipulation and reflow
// old: $(window).scroll(checkInView);
//
// By the way, iOS (iPad, iPhone, ...) seems to not execute, or at least delays
// intervals while the user scrolls. Therefore the inview event might fire a bit late there
//
// Don't waste cycles with an interval until we get at least one element that
// has bound to the inview event.
if (!timer && !$.isEmptyObject(inviewObjects)) {
timer = setInterval(checkInView, 333);
}
},
remove: function(data) {
try { delete inviewObjects[data.guid + "-" + this[expando]]; } catch(e) {}
// Clear interval when we no longer have any elements listening
if ($.isEmptyObject(inviewObjects)) {
clearInterval(timer);
timer = null;
}
}
};
function checkInView() {
// Fuck IE and its quirks, we're doing this the right way.
var $elements = $();
$.each(inviewObjects, function(i, inviewObject) {
var selector = inviewObject.data.selector,
$element = inviewObject.$element;
$elements = $elements.add(selector ? $element.find(selector) : $element);
});
if ($elements.length) {
for (var i = 0; i < $elements.length; i++) {
if (!$elements[i]) {
continue;
} else if (!$.contains(documentElement, $elements[i])) {
delete $elements[i];
continue;
}
var $el = $($elements[i]),
inView = $el.data('inview'),
rect = $el[0].getBoundingClientRect(),
height = $el.height(),
width = $el.width();
if (rect.top >= (0 - height + yMargin) &&
rect.left >= (0 - width + xMargin) &&
rect.bottom <= ((w.innerHeight || documentElement.clientHeight) + height - yMargin) &&
rect.right <= ((w.innerWidth || documentElement.clientWidth) + width - xMargin)) {
if (!inView) {
// object has entered viewport
$el.data('inview', true).trigger('inview', [true]);
}
} else if (inView) {
// object has left viewport
$el.data('inview', false).trigger('inview', [false]);
}
}
}
}
})(jQuery);