Skip to content

Commit 0cd66f6

Browse files
movedoamarcj
authored andcommitted
Use ResizeObserver when available and check for initial invisible elements (marcj#213)
ResizeObserver is Chrome only at the moment. When a resize sensor has been added to an invisible element, then we check coming with this commit every frame whether it is actually visible (rendered) and then start the sensor process. Otherwise the sensor would just not work on initial invisible elements.
1 parent a1ec6e4 commit 0cd66f6

File tree

1 file changed

+75
-31
lines changed

1 file changed

+75
-31
lines changed

src/ResizeSensor.js

Lines changed: 75 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@
8383
* @constructor
8484
*/
8585
var ResizeSensor = function(element, callback) {
86+
87+
var observer;
88+
8689
/**
8790
*
8891
* @constructor
@@ -94,9 +97,9 @@
9497
};
9598

9699
var i, j;
97-
this.call = function() {
100+
this.call = function(sizeInfo) {
98101
for (i = 0, j = q.length; i < j; i++) {
99-
q[i].call();
102+
q[i].call(this, sizeInfo);
100103
}
101104
};
102105

@@ -152,32 +155,50 @@
152155
var expand = element.resizeSensor.childNodes[0];
153156
var expandChild = expand.childNodes[0];
154157
var shrink = element.resizeSensor.childNodes[1];
155-
var dirty, rafId, newWidth, newHeight;
158+
159+
var dirty, rafId;
156160
var size = getElementSize(element);
157161
var lastWidth = size.width;
158162
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 () {
169167
expandChild.style.width = '100000px';
170168
expandChild.style.height = '100000px';
171-
169+
172170
expand.scrollLeft = 100000;
173171
expand.scrollTop = 100000;
174-
172+
175173
shrink.scrollLeft = 100000;
176174
shrink.scrollTop = 100000;
175+
};
177176

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+
}
180199
}
200+
201+
resetExpandShrink();
181202
};
182203
element.resizeSensor.resetSensor = reset;
183204

@@ -186,19 +207,17 @@
186207

187208
if (!dirty) return;
188209

189-
lastWidth = newWidth;
190-
lastHeight = newHeight;
210+
lastWidth = size.width;
211+
lastHeight = size.height;
191212

192213
if (element.resizedAttached) {
193-
element.resizedAttached.call();
214+
element.resizedAttached.call(size);
194215
}
195216
};
196217

197218
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;
202221

203222
if (dirty && !rafId) {
204223
rafId = requestAnimationFrame(onResized);
@@ -218,16 +237,41 @@
218237
addEvent(expand, 'scroll', onScroll);
219238
addEvent(shrink, 'scroll', onScroll);
220239

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+
});
223266
}
224-
225-
forEachElement(element, function(elem){
226-
attachResizeEvent(elem, callback);
227-
});
228267

229268
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+
}
231275
};
232276

233277
this.reset = function() {

0 commit comments

Comments
 (0)