/** * Get bounding client rect of given element */ import { getStyleComputedProperty } from './getStyleComputedProperty'; import { getBordersSize } from './getBordersSize'; import { getWindowSizes } from './getWindowSizes'; import { getScroll } from './getScroll'; import { getClientRect } from './getClientRect'; import { isIE } from './isIE'; import { Offsets } from '../models'; export function getBoundingClientRect(element: HTMLElement): Offsets { let rect: any = {}; // IE10 10 FIX: Please, don't ask, the element isn't // considered in DOM in some circumstances... // This isn't reproducible in IE10 compatibility mode of IE11 try { if (isIE(10)) { rect = element.getBoundingClientRect(); const scrollTop = getScroll(element, 'top'); const scrollLeft = getScroll(element, 'left'); rect.top += scrollTop; rect.left += scrollLeft; rect.bottom += scrollTop; rect.right += scrollLeft; } else { rect = element.getBoundingClientRect(); } } catch (e) { return undefined; } const result: any = { left: rect.left, top: rect.top, width: rect.right - rect.left, height: rect.bottom - rect.top }; // subtract scrollbar size from sizes const sizes: any = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {}; const width = sizes.width || element.clientWidth || result.right - result.left; const height = sizes.height || element.clientHeight || result.bottom - result.top; let horizScrollbar = element.offsetWidth - width; let vertScrollbar = element.offsetHeight - height; // if an hypothetical scrollbar is detected, we must be sure it's not a `border` // we make this check conditional for performance reasons if (horizScrollbar || vertScrollbar) { const styles = getStyleComputedProperty(element); horizScrollbar -= getBordersSize(styles, 'x'); vertScrollbar -= getBordersSize(styles, 'y'); result.width -= horizScrollbar; result.height -= vertScrollbar; } return getClientRect(result); }