From 0ab1e16ad9eae6b030e7f569973787664760e8e6 Mon Sep 17 00:00:00 2001 From: Steven Luscher Date: Fri, 10 May 2013 14:03:44 -0700 Subject: [PATCH] Droppable: Defer querying of offsetWidth and offsetHeight until they're required. Fixes #9339 - Droppable: offsetWidth and offsetHeight are queried unnecessarily causing synchronous reflow. (cherry picked from commit a4fc7a9e9664d44d65b971c90a0cad82e1e79344) --- ui/jquery.ui.droppable.js | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/ui/jquery.ui.droppable.js b/ui/jquery.ui.droppable.js index 552b24a5850..ec25aadc7e1 100644 --- a/ui/jquery.ui.droppable.js +++ b/ui/jquery.ui.droppable.js @@ -41,7 +41,8 @@ $.widget("ui.droppable", { }, _create: function() { - var o = this.options, + var proportions, + o = this.options, accept = o.accept; this.isover = false; @@ -51,8 +52,20 @@ $.widget("ui.droppable", { return d.is(accept); }; - //Store the droppable's proportions - this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; + this.proportions = function( /* valueToWrite */ ) { + if ( arguments.length ) { + // Store the droppable's proportions + proportions = arguments[ 0 ]; + } else { + // Retrieve or derive the droppable's proportions + return proportions ? + proportions : + proportions = { + width: this.element[ 0 ].offsetWidth, + height: this.element[ 0 ].offsetHeight + }; + } + }; // Add the reference and positions to the manager $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; @@ -198,10 +211,14 @@ $.ui.intersect = function(draggable, droppable, toleranceMode) { } var draggableLeft, draggableTop, - x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, - y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, - l = droppable.offset.left, r = l + droppable.proportions.width, - t = droppable.offset.top, b = t + droppable.proportions.height; + x1 = (draggable.positionAbs || draggable.position.absolute).left, + y1 = (draggable.positionAbs || draggable.position.absolute).top, + x2 = x1 + draggable.helperProportions.width, + y2 = y1 + draggable.helperProportions.height, + l = droppable.offset.left, + t = droppable.offset.top, + r = l + droppable.proportions().width, + b = t + droppable.proportions().height; switch (toleranceMode) { case "fit": @@ -214,7 +231,7 @@ $.ui.intersect = function(draggable, droppable, toleranceMode) { case "pointer": draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); - return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); + return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width ); case "touch": return ( (y1 >= t && y1 <= b) || // Top edge touching @@ -254,7 +271,7 @@ $.ui.ddmanager = { // Filter out elements in the current dragged item for (j=0; j < list.length; j++) { if(list[j] === m[i].element[0]) { - m[i].proportions.height = 0; + m[i].proportions().height = 0; continue droppablesLoop; } } @@ -269,8 +286,8 @@ $.ui.ddmanager = { m[i]._activate.call(m[i], event); } - m[i].offset = m[i].element.offset(); - m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; + m[ i ].offset = m[ i ].element.offset(); + m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight }); }