How do I get the offset of an element from the current screen position?
I am trying to refactor my entire jQuery with pure Javascript, everything works for me except for a special value. I get a different value depending on the browser vendor for this code:
With jQuery, I would use:
var topSelected = figure.offset().top - $(window).scrollTop();
Here's my (not working) attempt at using the DOM without jQuery:
var rect = figure.getBoundingClientRect(),
topSelected = (rect.top + document.body.scrollTop) - window.pageYOffset;
I am getting the same value for topSelected in Chrome with this code, but not for FF. The value that is different from browser to browser document.body.scrollTop
.
What is the correct way to get the difference between the offset of an element and the top of the scroll using the DOM API?
I need to support IE9 +, Firefox and Chrome.
source to share
I found a solution for this:
var rect = figure.getBoundingClientRect(),
topSelected = (rect.top + (document.documentElement.scrollTop || document.body.scrollTo)) - window.pageYOffset;
What it does is check the value document.documentElement.scrollTop
. In Chrome this always returns 0. So if 0 is returned, it document.body
is given as a function element scrollTop
outside the parenthesis.
TL; DR
To get the offset correctly:
Firefox -> document.documentElement
Chrome -> document.body
source to share
function getPosition(element) {
var xPosition = 0,
yPosition = 0;
while (element) {
xPosition += (element.offsetLeft + element.clientLeft);
yPosition += (element.offsetTop + element.clientTop);
element = element.offsetParent;
}
return {
x: xPosition,
y: yPosition
};
}
function getScroll() {
return {
x: document.documentElement.scrollLeft || document.body.scrollLeft,
y: document.documentElement.scrollTop || document.body.scrollTop
};
}
document.getElementById('test').addEventListener('click', function() {
var pos = getPosition(this),
scroll = getScroll(),
diff = (pos.x - scroll.x) + ',' + (pos.y - scroll.y);
this.childNodes[0].nodeValue = diff;
console.log(diff);
}, false);
body {
height: 1000px;
width: 1000px;
font-family: Consolas, monospace;
}
#test {
display: inline-block;
border: 3px solid;
padding: 10px;
margin-top: 300px;
margin-left: 300px;
}
<div id='test'>Element</div>
Summary:
The final set of functions might look like this:
function getPosition(element) {
var xPosition = 0,
yPosition = 0;
while (element) {
xPosition += (element.offsetLeft + element.clientLeft);
yPosition += (element.offsetTop + element.clientTop);
element = element.offsetParent;
}
return {
x: xPosition,
y: yPosition
};
}
function getScroll() {
return {
x: document.documentElement.scrollLeft || document.body.scrollLeft,
y: document.documentElement.scrollTop || document.body.scrollTop
};
}
function getWindowOffset(element) {
var pos = getPosition(element),
scroll = getScroll();
return {
x: (pos.x - scroll.x),
y: (pos.y - scroll.y)
};
}
Then just call getWindowOffset()
your element to get its position relative to the window.
source to share