Robust Get Element Dimension Function
As mentioned earlier this week, today we will be discussing a ‘getDimension’ function that corrects for certain styles (”display:none” and “overflow:hidden”) that cause an element to not have the proper height/width. This method contains generic logic that will determine if the element is “display:none” or “overflow:hidden”, whether styled inline or via CSS (thanks to YUI), and temporarily correct those styles to determine the actual height/width of the element. It works with any element (not just block level), will restore any styles that it changes, and allows you to override the default correction behavior.
Example 1: getDimension
Dom.getDimension = function(elem, ignoreDisplay, ignoreOverflow) { var node = Dom.get(elem), x = 0, y = 0, width = 0, height = 0; // node exists if (node) { var stl = node.style, originalDisplay = Dom.getStyle(node, 'display'), originalOverflow = Dom.getStyle(node, 'overflow'), originalPosition = Dom.getStyle(node, 'position'), originalVisibility = Dom.getStyle(node, 'visibility'), originalHeight = node.offsetHeight, correctDisplay = 'none' === originalDisplay && ! ignoreDisplay, correctOverflow = 'hidden' === originalOverflow && ! ignoreOverflow; // not displayed; temporarily display if (correctDisplay) { stl.visibility = 'hidden'; stl.position = 'absolute'; stl.display = 'block'; } // overflow hidden; attempt to correct if (correctOverflow) { stl.visibility = 'hidden'; stl.position = 'absolute'; stl.height = 'auto'; } // determine dimensions var region = Dom.getRegion(node); x = region.left; y = right.top; width = region.right - x; height = region.bottom - y; // restore overflow if (correctOverflow) { stl.height = originalHeight + 'px'; stl.visibility = originalVisibility; stl.position = originalPosition; } // restore corrected display if (correctDisplay) { stl.visibility = originalVisibility; stl.position = originalPosition; stl.display = originalDisplay; } } return {x: x, y: y, height: height, width: width}; };
*Note: I assume that you are using YUI’s “yahoo-dom-event.js” and that you have a shortcut “Dom” that points to ‘YAHOO.util.Dom”.
First we ensure that the element is an Element object, not an ID string, and initialize default value of ZERO for each dimension. When the node exists in the DOM we fetch the required styles using the YUI “Dom.getStyle” method, which corrects for styles applied via CSS, and determine if we need to correct for “display:none” or “overflow:hidden”. You can prevent these corrections if you set either ‘ignoreDisplay’ or ‘ignoreOverflow’ to true. If we need to correct the display, we style the visibility to ‘hidden’, so it won’t appear when we style the element “display:block”, and ‘position’ it ‘absolute’ so that it won’t move other elements around in the DOM. If we need to correct for the overflow, we do the same, but instead of applying “display:block”, we set the ‘height’ to ‘auto’, which will cause the element height to reflect its contents. Then we determine the dimensions using the YUI “Dom.getRegion” method, which returns the ‘top’, ‘right’, ‘bottom’, and ‘left’ values of the element. Lastly, before returning the dimensions, we restore any ‘height’, ‘visibility’, ‘position’, and/or ‘display’ styles to their original values.
This method has fairly simple logic, but is immensely helpful if you need the full dimension of elements that are not or might not be displayed. I put together a test page, so that you can see ‘getDimension’ in action.
