|
83 | 83 | * @constructor
|
84 | 84 | */
|
85 | 85 | var ResizeSensor = function(element, callback) {
|
| 86 | + |
| 87 | + var observer; |
| 88 | + |
86 | 89 | /**
|
87 | 90 | *
|
88 | 91 | * @constructor
|
|
94 | 97 | };
|
95 | 98 |
|
96 | 99 | var i, j;
|
97 |
| - this.call = function() { |
| 100 | + this.call = function(sizeInfo) { |
98 | 101 | for (i = 0, j = q.length; i < j; i++) {
|
99 |
| - q[i].call(); |
| 102 | + q[i].call(this, sizeInfo); |
100 | 103 | }
|
101 | 104 | };
|
102 | 105 |
|
|
152 | 155 | var expand = element.resizeSensor.childNodes[0];
|
153 | 156 | var expandChild = expand.childNodes[0];
|
154 | 157 | var shrink = element.resizeSensor.childNodes[1];
|
155 |
| - var dirty, rafId, newWidth, newHeight; |
| 158 | + |
| 159 | + var dirty, rafId; |
156 | 160 | var size = getElementSize(element);
|
157 | 161 | var lastWidth = size.width;
|
158 | 162 | var lastHeight = size.height;
|
159 |
| - |
160 |
| - var reset = function() { |
161 |
| - //set display to block, necessary otherwise hidden elements won't ever work |
162 |
| - var invisible = element.offsetWidth === 0 && element.offsetHeight === 0; |
163 |
| - |
164 |
| - if (invisible) { |
165 |
| - var saveDisplay = element.style.display; |
166 |
| - element.style.display = 'block'; |
167 |
| - } |
168 |
| - |
| 163 | + var initialHiddenCheck = true, resetRAF_id; |
| 164 | + |
| 165 | + |
| 166 | + var resetExpandShrink = function () { |
169 | 167 | expandChild.style.width = '100000px';
|
170 | 168 | expandChild.style.height = '100000px';
|
171 |
| - |
| 169 | + |
172 | 170 | expand.scrollLeft = 100000;
|
173 | 171 | expand.scrollTop = 100000;
|
174 |
| - |
| 172 | + |
175 | 173 | shrink.scrollLeft = 100000;
|
176 | 174 | shrink.scrollTop = 100000;
|
| 175 | + }; |
177 | 176 |
|
178 |
| - if (invisible) { |
179 |
| - element.style.display = saveDisplay; |
| 177 | + var reset = function() { |
| 178 | + // Check if element is hidden |
| 179 | + if (initialHiddenCheck) { |
| 180 | + if (!expand.scrollTop && !expand.scrollLeft) { |
| 181 | + |
| 182 | + // reset |
| 183 | + resetExpandShrink(); |
| 184 | + |
| 185 | + // Check in next frame |
| 186 | + if (!resetRAF_id){ |
| 187 | + resetRAF_id = requestAnimationFrame(function(){ |
| 188 | + resetRAF_id = 0; |
| 189 | + |
| 190 | + reset(); |
| 191 | + }); |
| 192 | + } |
| 193 | + |
| 194 | + return; |
| 195 | + } else { |
| 196 | + // Stop checking |
| 197 | + initialHiddenCheck = false; |
| 198 | + } |
180 | 199 | }
|
| 200 | + |
| 201 | + resetExpandShrink(); |
181 | 202 | };
|
182 | 203 | element.resizeSensor.resetSensor = reset;
|
183 | 204 |
|
|
186 | 207 |
|
187 | 208 | if (!dirty) return;
|
188 | 209 |
|
189 |
| - lastWidth = newWidth; |
190 |
| - lastHeight = newHeight; |
| 210 | + lastWidth = size.width; |
| 211 | + lastHeight = size.height; |
191 | 212 |
|
192 | 213 | if (element.resizedAttached) {
|
193 |
| - element.resizedAttached.call(); |
| 214 | + element.resizedAttached.call(size); |
194 | 215 | }
|
195 | 216 | };
|
196 | 217 |
|
197 | 218 | var onScroll = function() {
|
198 |
| - var size = getElementSize(element); |
199 |
| - var newWidth = size.width; |
200 |
| - var newHeight = size.height; |
201 |
| - dirty = newWidth != lastWidth || newHeight != lastHeight; |
| 219 | + size = getElementSize(element); |
| 220 | + dirty = size.width !== lastWidth || size.height !== lastHeight; |
202 | 221 |
|
203 | 222 | if (dirty && !rafId) {
|
204 | 223 | rafId = requestAnimationFrame(onResized);
|
|
218 | 237 | addEvent(expand, 'scroll', onScroll);
|
219 | 238 | addEvent(shrink, 'scroll', onScroll);
|
220 | 239 |
|
221 |
| - // Fix for custom Elements |
222 |
| - requestAnimationFrame(reset); |
| 240 | + // Fix for custom Elements |
| 241 | + requestAnimationFrame(reset); |
| 242 | + } |
| 243 | + |
| 244 | + if (typeof ResizeObserver !== "undefined") { |
| 245 | + observer = new ResizeObserver(function(element){ |
| 246 | + forEachElement(element, function (elem) { |
| 247 | + callback.call( |
| 248 | + this, |
| 249 | + { |
| 250 | + width: elem.contentRect.width, |
| 251 | + height: elem.contentRect.height |
| 252 | + } |
| 253 | + ); |
| 254 | + }); |
| 255 | + }); |
| 256 | + if (element !== undefined) { |
| 257 | + forEachElement(element, function(elem){ |
| 258 | + observer.observe(elem); |
| 259 | + }); |
| 260 | + } |
| 261 | + } |
| 262 | + else { |
| 263 | + forEachElement(element, function(elem){ |
| 264 | + attachResizeEvent(elem, callback); |
| 265 | + }); |
223 | 266 | }
|
224 |
| - |
225 |
| - forEachElement(element, function(elem){ |
226 |
| - attachResizeEvent(elem, callback); |
227 |
| - }); |
228 | 267 |
|
229 | 268 | this.detach = function(ev) {
|
230 |
| - ResizeSensor.detach(element, ev); |
| 269 | + if (typeof ResizeObserver != "undefined") { |
| 270 | + observer.unobserve(element); |
| 271 | + } |
| 272 | + else { |
| 273 | + ResizeSensor.detach(element, ev); |
| 274 | + } |
231 | 275 | };
|
232 | 276 |
|
233 | 277 | this.reset = function() {
|
|
0 commit comments