|
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