|
15 | 15 | factory(jQuery);
|
16 | 16 | }
|
17 | 17 | }(function ($) {
|
18 |
| - var inviewObjects = {}, viewportSize, viewportOffset, |
19 |
| - d = document, w = window, documentElement = d.documentElement, expando = $.expando, timer; |
| 18 | + |
| 19 | + var inviewObjects = [], viewportSize, viewportOffset, |
| 20 | + d = document, w = window, documentElement = d.documentElement, timer; |
20 | 21 |
|
21 | 22 | $.event.special.inview = {
|
22 | 23 | add: function(data) {
|
23 |
| - inviewObjects[data.guid + "-" + this[expando]] = { data: data, $element: $(this) }; |
24 |
| - |
| 24 | + inviewObjects.push({ data: data, $element: $(this), element: this }); |
25 | 25 | // Use setInterval in order to also make sure this captures elements within
|
26 | 26 | // "overflow:scroll" elements or elements that appeared in the dom tree due to
|
27 | 27 | // dom manipulation and reflow
|
|
32 | 32 | //
|
33 | 33 | // Don't waste cycles with an interval until we get at least one element that
|
34 | 34 | // has bound to the inview event.
|
35 |
| - if (!timer && !$.isEmptyObject(inviewObjects)) { |
| 35 | + if (!timer && inviewObjects.length) { |
36 | 36 | timer = setInterval(checkInView, 250);
|
37 | 37 | }
|
38 | 38 | },
|
39 | 39 |
|
40 | 40 | remove: function(data) {
|
41 |
| - try { delete inviewObjects[data.guid + "-" + this[expando]]; } catch(e) {} |
| 41 | + for (var i=0; i<inviewObjects.length; i++) { |
| 42 | + var inviewObject = inviewObjects[i]; |
| 43 | + if (inviewObject.element === this && inviewObject.data.guid === data.guid) { |
| 44 | + inviewObjects.splice(i, 1); |
| 45 | + break; |
| 46 | + } |
| 47 | + } |
42 | 48 |
|
43 | 49 | // Clear interval when we no longer have any elements listening
|
44 |
| - if ($.isEmptyObject(inviewObjects)) { |
| 50 | + if (!inviewObjects.length) { |
45 | 51 | clearInterval(timer);
|
46 | 52 | timer = null;
|
47 | 53 | }
|
|
77 | 83 | }
|
78 | 84 |
|
79 | 85 | function checkInView() {
|
80 |
| - var $elements = [], elementsLength, i = 0; |
| 86 | + if (!inviewObjects.length) { |
| 87 | + return; |
| 88 | + } |
81 | 89 |
|
82 |
| - $.each(inviewObjects, function(i, inviewObject) { |
| 90 | + var i = 0, $elements = $.map(inviewObjects, function(inviewObject) { |
83 | 91 | var selector = inviewObject.data.selector,
|
84 | 92 | $element = inviewObject.$element;
|
85 |
| - $elements.push(selector ? $element.find(selector) : $element); |
| 93 | + return selector ? $element.find(selector) : $element; |
86 | 94 | });
|
87 | 95 |
|
88 |
| - elementsLength = $elements.length; |
89 |
| - if (elementsLength) { |
90 |
| - viewportSize = viewportSize || getViewportSize(); |
91 |
| - viewportOffset = viewportOffset || getViewportOffset(); |
| 96 | + viewportSize = viewportSize || getViewportSize(); |
| 97 | + viewportOffset = viewportOffset || getViewportOffset(); |
92 | 98 |
|
93 |
| - for (; i<elementsLength; i++) { |
94 |
| - // Ignore elements that are not in the DOM tree |
95 |
| - if (!$.contains(documentElement, $elements[i][0])) { |
96 |
| - continue; |
97 |
| - } |
| 99 | + for (; i<inviewObjects.length; i++) { |
| 100 | + // Ignore elements that are not in the DOM tree |
| 101 | + if (!$.contains(documentElement, $elements[i][0])) { |
| 102 | + continue; |
| 103 | + } |
98 | 104 |
|
99 |
| - var $element = $($elements[i]), |
100 |
| - elementSize = { height: $element.height(), width: $element.width() }, |
101 |
| - elementOffset = $element.offset(), |
102 |
| - inView = $element.data('inview'), |
103 |
| - visiblePartX, |
104 |
| - visiblePartY, |
105 |
| - visiblePartsMerged; |
106 |
| - |
107 |
| - // Don't ask me why because I haven't figured out yet: |
108 |
| - // viewportOffset and viewportSize are sometimes suddenly null in Firefox 5. |
109 |
| - // Even though it sounds weird: |
110 |
| - // It seems that the execution of this function is interferred by the onresize/onscroll event |
111 |
| - // where viewportOffset and viewportSize are unset |
112 |
| - if (!viewportOffset || !viewportSize) { |
113 |
| - return; |
114 |
| - } |
| 105 | + var $element = $($elements[i]), |
| 106 | + elementSize = { height: $element.height(), width: $element.width() }, |
| 107 | + elementOffset = $element.offset(), |
| 108 | + inView = $element.data('inview'); |
| 109 | + |
| 110 | + // Don't ask me why because I haven't figured out yet: |
| 111 | + // viewportOffset and viewportSize are sometimes suddenly null in Firefox 5. |
| 112 | + // Even though it sounds weird: |
| 113 | + // It seems that the execution of this function is interferred by the onresize/onscroll event |
| 114 | + // where viewportOffset and viewportSize are unset |
| 115 | + if (!viewportOffset || !viewportSize) { |
| 116 | + return; |
| 117 | + } |
115 | 118 |
|
116 |
| - if (elementOffset.top + elementSize.height > viewportOffset.top && |
117 |
| - elementOffset.top < viewportOffset.top + viewportSize.height && |
118 |
| - elementOffset.left + elementSize.width > viewportOffset.left && |
119 |
| - elementOffset.left < viewportOffset.left + viewportSize.width) { |
120 |
| - visiblePartX = (viewportOffset.left > elementOffset.left ? |
121 |
| - 'right' : (viewportOffset.left + viewportSize.width) < (elementOffset.left + elementSize.width) ? |
122 |
| - 'left' : 'both'); |
123 |
| - visiblePartY = (viewportOffset.top > elementOffset.top ? |
124 |
| - 'bottom' : (viewportOffset.top + viewportSize.height) < (elementOffset.top + elementSize.height) ? |
125 |
| - 'top' : 'both'); |
126 |
| - visiblePartsMerged = visiblePartX + "-" + visiblePartY; |
127 |
| - if (!inView || inView !== visiblePartsMerged) { |
128 |
| - $element.data('inview', visiblePartsMerged).trigger('inview', [true, visiblePartX, visiblePartY]); |
129 |
| - } |
130 |
| - } else if (inView) { |
131 |
| - $element.data('inview', false).trigger('inview', [false]); |
| 119 | + if (elementOffset.top + elementSize.height > viewportOffset.top && |
| 120 | + elementOffset.top < viewportOffset.top + viewportSize.height && |
| 121 | + elementOffset.left + elementSize.width > viewportOffset.left && |
| 122 | + elementOffset.left < viewportOffset.left + viewportSize.width) { |
| 123 | + if (!inView) { |
| 124 | + $element.data('inview', true).trigger('inview', [true]); |
132 | 125 | }
|
| 126 | + } else if (inView) { |
| 127 | + $element.data('inview', false).trigger('inview', [false]); |
133 | 128 | }
|
134 | 129 | }
|
135 | 130 | }
|
|
0 commit comments