Reputation: 145
I'm trying to develop a function which move a div-Element to the same height as the hovered element. For this I used offsetTop but it always returns 0 and I don't get what I'm doing wrong.
$( document ).ready(function() {
const handle = document.querySelector('#handle');
const headers = document.querySelectorAll('.et_pb_accordion_item_0, .et_pb_accordion_item_1, .et_pb_accordion_item_2')
.forEach(el => {
el.addEventListener('mouseover', e => {
handle.style.top = `${e.currentTarget.offsetTop}px`;
});
});
});
I also tried to use getBoundingClientRect().top
but it return different values if I scroll dwon
Upvotes: 10
Views: 19642
Reputation: 5112
The offsetTop property is relative to the top padding edge of the offsetParent, whereas getBoundingClientRect is relative to the viewPort. If you use position: relative on the parent and there is no distance from the outer border of the current element (including its margin) to the top padding edge of the offsetParent, then the value will logically be zero.
Upvotes: 0
Reputation: 2455
I was having the same issue with offsetTop = 0 in some instances, but not others. For that I am still not sure why!
I had used getBoundingClientRect
before with better success, so I adjusted my code to use that approach. As OP said, it gives different numbers depending on how far you have scrolled the window, but we can add that scroll position and get consistent numbers.
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
let rectViewport = el.getBoundingClientRect();
let top = rectViewport.top + scrollTop;
window.pageYOffset
is deprecated but works as a "fallback" in this ||
method.rectViewport
is our element el
and utilizing getBoundingClientRect()
top
is the combination of the el's viewport top and scroll topLet's imagine we were scrolled down 200ish pixels, we would see scrollTop to match that. And our element was 2000+ pixels down from the current viewport. We can combine to get 2200+ of the actual window. To see the result, combine with something fun like:
window.scrollTo({
top: top,
behavior: 'smooth'
});
Upvotes: 0
Reputation: 1335
Calculate the correct offsetTop
(same solution is valid for offsetLeft
), recursing all parents until you get null with something like this:
function getOffsetTop(element) {
return element ? (element.offsetTop + getOffsetTop(element.offsetParent)) : 0;
}
Then use that function on your code getOffsetTop(e.currentTarget)
instead of getting directly e.currentTarget.offsetTop
.
Upvotes: 9
Reputation: 2019
You should use the getBoundingClientRect() as follow:
var ele = document.getElementById('elementId');
var offset = ele.getBoundingClientRect();
// you can use
offset.left;
offset.top;
It works for me.
Upvotes: 18