I'm trying to refactor out all my jQuery with pure Javascript, I got everything working except a very specific value. I'm getting a different value depending in the browser vendor for this code :
With jQuery I'd use:
var topSelected = figure.offset().top - $(window).scrollTop();
Here is my (non working) attempt using the DOM without jQuery:
var rect = figure.getBoundingClientRect(),
topSelected = (rect.top + document.body.scrollTop) - window.pageYOffset;
I'm getting the exact same value for topSelected in Chrome with this code, but not for FF. The value that differs from browser to browser is document.body.scrollTop
.
What is the correct way to get the difference between the offset of an element and the scroll top using the DOM API?
I need to support IE9+, Firefox and Chrome.
I'm trying to refactor out all my jQuery with pure Javascript, I got everything working except a very specific value. I'm getting a different value depending in the browser vendor for this code :
With jQuery I'd use:
var topSelected = figure.offset().top - $(window).scrollTop();
Here is my (non working) attempt using the DOM without jQuery:
var rect = figure.getBoundingClientRect(),
topSelected = (rect.top + document.body.scrollTop) - window.pageYOffset;
I'm getting the exact same value for topSelected in Chrome with this code, but not for FF. The value that differs from browser to browser is document.body.scrollTop
.
What is the correct way to get the difference between the offset of an element and the scroll top using the DOM API?
I need to support IE9+, Firefox and Chrome.
Share Improve this question edited Dec 21, 2014 at 11:58 merqurio asked Dec 21, 2014 at 11:08 merquriomerqurio 94112 silver badges25 bronze badges 10- 3 "I'm trying to replace all jQuery with pure Javascript" No, you're trying to replace your use of jQuery with pure DOM. Both use JavaScript. – T.J. Crowder Commented Dec 21, 2014 at 11:10
-
3
Since jQuery is pure JavaScript, you can just look at the part that says
scrollTop
and check if it does anything different than gettingpageYOffset
. – Jonathan Commented Dec 21, 2014 at 11:10 - You might want to mention what browsers you have to support. – Benjamin Gruenbaum Commented Dec 21, 2014 at 11:13
- 4 Your issues are exactly why people use libraries such as jQuery. There's no nice way of getting the value you want without lots of browser-specific code. – Phylogenesis Commented Dec 21, 2014 at 11:13
- Good idea ! I'm going to check it ! – merqurio Commented Dec 21, 2014 at 11:14
2 Answers
Reset to default 4
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:
A final function set 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()
on your element to get its position relative to the window.
I have found a solution for this :
var rect = figure.getBoundingClientRect(),
topSelected = (rect.top + (document.documentElement.scrollTop || document.body.scrollTo)) - window.pageYOffset;
What it does is to check the value of document.documentElement.scrollTop
. In Chrome this always returns 0. So if 0 is returned, document.body
is given as element to the scrollTop
function outside the parenthesis.
TL;DR
To get the offset correctly:
Firefox --> document.documentElement
Chrome --> document.body