Created
December 8, 2017 08:59
-
-
Save perry-mitchell/2b29018b07f73e431df5d454bdd9b9e2 to your computer and use it in GitHub Desktop.
True element offset (from document) calculation with debouncing/memoization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import mem from "mem"; | |
const ELEMENT_STYLE_CACHE_TIME = 3000; | |
let __memoizedGetElementStyle; | |
export function getElementOffset(target) { | |
__memoizedGetElementStyle = __memoizedGetElementStyle || mem(getElementStyle, { maxAge: ELEMENT_STYLE_CACHE_TIME }); | |
const boundingRect = target.getBoundingClientRect(); | |
const bodyStyle = __memoizedGetElementStyle(document.body); | |
let x = parseInt(bodyStyle.marginLeft || 0, 10), | |
y = parseInt(bodyStyle.marginTop || 0, 10), | |
el = target; | |
while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) { | |
const elStyle = __memoizedGetElementStyle(el); | |
const isFixed = /fixed/.test(elStyle.position); | |
x += el.offsetLeft; // - el.scrollLeft; | |
y += el.offsetTop; // - el.scrollTop; | |
if (isFixed) { | |
x += document.body.scrollLeft; | |
y += document.body.scrollTop; | |
break; | |
} | |
el = el.offsetParent; | |
} | |
return { | |
top: y, | |
left: x, | |
width: boundingRect.width, | |
height: boundingRect.height | |
}; | |
} | |
function getElementStyle(element) { | |
return window.getComputedStyle(element); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment