29

I have a scrolling element inside a window.

Say a division having a class "currentContainer" with overflow auto and that division contains huge amount of text so that it is definitely large enough to be scrolling.

Now I have to do some calculations based on how much the "currentContainer" has scrolled down + what is the offset of a specific element from its parent scrolling div (that is "currentCoantainer").

But while calculating offset I always get the offset of the inner child element with regard to window not with the "currentContainer".

JS FIDDLE

@Shikkediel I also tried using position().top instead of offset().top but is is also giving the same result. Have a look at it :

JS FIDDLE 2

Please do not suggest using :

$("<reference of scrolling element").scrollTop() 
+ 
$("<reference of child element whose offset I want to calculate>").offset().top

Because this is going to complicate my actual calculations which I am about to do beyond this.

Reason for why I do not want to use the above mentioned approach is that I am trying to modify an existing code which is already too messy but is working perfectly with regard to window I just have to update it so that it starts working relative to its parent scrolling div.

I tried using above mentioned approach but it opened a box of crabs for me. because functions are too much tightly coupled. So I think if I can get simple and straight solution i.e. replacing .offset().top with something else.


I tried debugging the code and still no luck I have added the actual code at http://jsfiddle.net/arpitajain/kwkm7com/

P.S. It is actual code but not complete I think The rest of the code was not needed for this error.

HaveNoDisplayName
  • 8,291
  • 106
  • 37
  • 47
Arpita
  • 1,386
  • 1
  • 15
  • 35

4 Answers4

23

You could just subtract the offset of the parent element from the offset of the child element. Will that complicate the other things you need to do as well?

$(".getoffset").offset().top - $(".getoffset").offsetParent().offset().top

http://jsfiddle.net/kmLr07oh/2/

Tim Mullen
  • 624
  • 5
  • 8
  • Great Answer, Thank you! – Mohan Dec 16 '21 at 08:58
  • What is to non-jquery way? jQuery is outdated now. – Mario Eis Mar 21 '23 at 12:42
  • Some notes to add: \ 1. Make sure your Parent_Div is **not dynamically changing**. \ -- so better use a `**fixed element reference** for the Parent_Div`, inside of using something like `Child_Element_ToGetOffsetRelToParentDiv.parent` \ 1. If you are inside a **scrollable Parent_Div**, maybe you would like to add **`+ Parent_Div.scrollTop;`**. \ so eg: `const offset = Child_Element_ToGetOffsetRelToParentDiv.getBoundingClientRect().top - Parent_Div.getBoundingClientRect().top + Parent_Div.scrollTop;` – Nor.Z Sep 02 '23 at 14:36
12

This is probably what you are looking for

var scrollOffset = $('.container .element')[0].offsetTop - $('.container')[0].offsetTop;

and in Vanilla JS

var scrollOffset = document.querySelector('.container .element').offsetTop - document.querySelector('.container').offsetTop;

———————————

If you want background this should get you most of the way there:

// Position of first element relative to container top
var scrollTop = $(".container .element").offset().top - $(".container").offset().top;

// Position of selected element relative to container top
var targetTop = $(".container > *").offset().top - $(".container").offset().top;

// The offset of a scrollable container
var scrollOffset = scrollTop - targetTop;

// Scroll untill target element is at the top of its container
$(".container").scrollTop(scrollOffset);

Also see: Calculate offset top of elements inside of a scrollable div

Quinn Keaveney
  • 1,248
  • 1
  • 17
  • 39
6

A vanilla Javascript solution would be:

const el = document.querySelector('.getoffset');
const offset = el.getBoundingClientRect().top - el.offsetParent.getBoundingClientRect().top;

Fiddle: http://jsfiddle.net/njb1xcz0/

andreivictor
  • 7,628
  • 3
  • 48
  • 75
  • Doesn't work, the resulting numbers are way too big. The entire space before the scrolling div is also added which is not correct. – ygoe Jun 14 '21 at 14:19
  • in the fiddle that I've posted, the values calculated with the vanilla JS are identical to those calculated via jquery. please provide a fiddle so that I can reproduce your issue. – andreivictor Jun 14 '21 at 14:29
  • 1
    I think my scroll container might have missed the `position: relative` which another comment somewhere mentioned. None of the answers I found about that topic included that important point, otherwise `offsetTop` (the main part of any solution) just doesn't work. – ygoe Jun 14 '21 at 18:28
0

In my test

//has the same value
console.log(
    'compare:',
    $("#element").offset().left - $("#container").offset().left,
    $("#element").position().left
);

Witch mean it gets absolute position to parent. To get relative position to parent, I use:

let relative_position_x = Element.position().left + scroller.scrollLeft();
let relative_position_y = Element.position().top + scroller.scrollTop();
Corxit Sun
  • 618
  • 6
  • 8