Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
function getStyle(elem, prop) {
return window.getComputedStyle(elem).getPropertyValue(prop);
}
function bodyOffset( body ) {
let top = body.offsetTop,
left = body.offsetLeft;
let doesNotIncludeMarginInBodyOffset; // TODO
if (doesNotIncludeMarginInBodyOffset ) {
top += parseFloat( getStyle(body, 'marginTop') ) || 0;
left += parseFloat( getStyle(body, 'marginLeft') ) || 0;
}
return {
top: top, left: left
};
}
function getBoundingClientRect(elem) {
if (!elem || !elem.ownerDocument ) {
return null;
}
if (elem === elem.ownerDocument.body) {
return bodyOffset(elem);
}
let computedStyle,
offsetParent = elem.offsetParent,
doc = elem.ownerDocument,
docElem = doc.documentElement,
body = doc.body,
defaultView = doc.defaultView,
prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) :
elem.currentStyle,
top = elem.offsetTop,
left = elem.offsetLeft;
while ((elem = elem.parentNode) && elem !== body && elem !== docElem ) {
if (prevComputedStyle.position === 'fixed' ) {
break;
}
computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
top -= elem.scrollTop;
left -= elem.scrollLeft;
if ( elem === offsetParent ) {
top += elem.offsetTop;
left += elem.offsetLeft;
offsetParent = elem.offsetParent;
}
prevComputedStyle = computedStyle;
}
if (prevComputedStyle.position === 'relative' || prevComputedStyle.position === 'static') {
top += body.offsetTop;
left += body.offsetLeft;
}
if (prevComputedStyle.position === 'fixed') {
top += Math.max( docElem.scrollTop, body.scrollTop );
left += Math.max( docElem.scrollLeft, body.scrollLeft );
}
return {
top: top, left: left
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment