Skip to content

Commit a4fc7a9

Browse files
Steven Luschermikesherov
Steven Luscher
authored andcommitted
Droppable: Defer querying of offsetWidth and offsetHeight until they're required. Fixes #9339 - Droppable: offsetWidth and offsetHeight are queried unnecessarily causing synchronous reflow.
1 parent 6df5c1a commit a4fc7a9

File tree

1 file changed

+28
-11
lines changed

1 file changed

+28
-11
lines changed

ui/jquery.ui.droppable.js

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ $.widget("ui.droppable", {
4141
},
4242
_create: function() {
4343

44-
var o = this.options,
44+
var proportions,
45+
o = this.options,
4546
accept = o.accept;
4647

4748
this.isover = false;
@@ -51,8 +52,20 @@ $.widget("ui.droppable", {
5152
return d.is(accept);
5253
};
5354

54-
//Store the droppable's proportions
55-
this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
55+
this.proportions = function( /* valueToWrite */ ) {
56+
if ( arguments.length ) {
57+
// Store the droppable's proportions
58+
proportions = arguments[ 0 ];
59+
} else {
60+
// Retrieve or derive the droppable's proportions
61+
return proportions ?
62+
proportions :
63+
proportions = {
64+
width: this.element[ 0 ].offsetWidth,
65+
height: this.element[ 0 ].offsetHeight
66+
};
67+
}
68+
};
5669

5770
// Add the reference and positions to the manager
5871
$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
@@ -198,10 +211,14 @@ $.ui.intersect = function(draggable, droppable, toleranceMode) {
198211
}
199212

200213
var draggableLeft, draggableTop,
201-
x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
202-
y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
203-
l = droppable.offset.left, r = l + droppable.proportions.width,
204-
t = droppable.offset.top, b = t + droppable.proportions.height;
214+
x1 = (draggable.positionAbs || draggable.position.absolute).left,
215+
y1 = (draggable.positionAbs || draggable.position.absolute).top,
216+
x2 = x1 + draggable.helperProportions.width,
217+
y2 = y1 + draggable.helperProportions.height,
218+
l = droppable.offset.left,
219+
t = droppable.offset.top,
220+
r = l + droppable.proportions().width,
221+
b = t + droppable.proportions().height;
205222

206223
switch (toleranceMode) {
207224
case "fit":
@@ -214,7 +231,7 @@ $.ui.intersect = function(draggable, droppable, toleranceMode) {
214231
case "pointer":
215232
draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
216233
draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
217-
return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
234+
return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );
218235
case "touch":
219236
return (
220237
(y1 >= t && y1 <= b) || // Top edge touching
@@ -254,7 +271,7 @@ $.ui.ddmanager = {
254271
// Filter out elements in the current dragged item
255272
for (j=0; j < list.length; j++) {
256273
if(list[j] === m[i].element[0]) {
257-
m[i].proportions.height = 0;
274+
m[i].proportions().height = 0;
258275
continue droppablesLoop;
259276
}
260277
}
@@ -269,8 +286,8 @@ $.ui.ddmanager = {
269286
m[i]._activate.call(m[i], event);
270287
}
271288

272-
m[i].offset = m[i].element.offset();
273-
m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
289+
m[ i ].offset = m[ i ].element.offset();
290+
m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
274291

275292
}
276293

0 commit comments

Comments
 (0)