/** * Get bounding client rect of given element */ import { getStyleComputedProperty } from './getStyleComputedProperty'; import { getBordersSize } from './getBordersSize'; import { getWindowSizes } from './getWindowSizes'; import { getClientRect } from './getClientRect'; import { Offsets } from '../models'; import { isNumber } from './isNumeric'; export function getBoundingClientRect(element: HTMLElement): Offsets { const rect: Offsets = element.getBoundingClientRect(); // 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)) { // const scrollTop = getScroll(element, 'top'); // const scrollLeft = getScroll(element, 'left'); // if (rect && isNumber(rect.top) && isNumber(rect.left) && isNumber(rect.bottom) && isNumber(rect.right)) { // rect.top += scrollTop; // rect.left += scrollLeft; // rect.bottom += scrollTop; // rect.right += scrollLeft; // } // } // } catch (e) { // return rect; // } if (!(rect && isNumber(rect.top) && isNumber(rect.left) && isNumber(rect.bottom) && isNumber(rect.right))) { return rect; } const result: Offsets = { left: rect.left, top: rect.top, width: rect.right - rect.left, height: rect.bottom - rect.top }; // subtract scrollbar size from sizes const sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : undefined; const width = sizes?.width || element.clientWidth || isNumber(rect.right) && isNumber(result.left) && rect.right - result.left || 0; const height = sizes?.height || element.clientHeight || isNumber(rect.bottom) && isNumber(result.top) && rect.bottom - result.top || 0; 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); }