javascript - Get element position relative to page with overflows - Stack Overflow

I want to get the position of an element relative to the whole page, but the element is in a scrollable

I want to get the position of an element relative to the whole page, but the element is in a scrollable container, which makes the methods that are usually used, useless. (Talking about getBoundingClientRect(), offsetTop etc.)

As an example of what I mean:

In the "Basic Drag&Drop" section, if you get elements' Y position without scrolling the page, you get 626 for element.getBoundingClientRect().top

Now if you scroll down, so that the element almost touches the top of the window, you get 70 for the same exact same elmenent

But what I want, is the exact same value relative to the whole page, so the value shouldn't change after I scrolled. I know this would be the case for the default scroll behaviour, but in this case the body doesn't scroll, but its elements.

I want to get the position of an element relative to the whole page, but the element is in a scrollable container, which makes the methods that are usually used, useless. (Talking about getBoundingClientRect(), offsetTop etc.)

As an example of what I mean: https://material.angular.io/cdk/drag-drop/overview

In the "Basic Drag&Drop" section, if you get elements' Y position without scrolling the page, you get 626 for element.getBoundingClientRect().top

Now if you scroll down, so that the element almost touches the top of the window, you get 70 for the same exact same elmenent

But what I want, is the exact same value relative to the whole page, so the value shouldn't change after I scrolled. I know this would be the case for the default scroll behaviour, but in this case the body doesn't scroll, but its elements.

Share Improve this question asked Mar 30, 2021 at 1:03 Yassine ZeriouhYassine Zeriouh 5103 gold badges10 silver badges23 bronze badges 2
  • Does this answer work for you? stackoverflow./a/1480137 – Steve Commented Apr 1, 2021 at 16:21
  • @Steve Unfortunately not - in the Angular Drag & Drop case, the offsets stay the same after dragging the element to another position – Yassine Zeriouh Commented Apr 3, 2021 at 1:20
Add a ment  | 

2 Answers 2

Reset to default 7 +75

If you can identify the scrollable container which your element rests in, you can simply add its vertical scroll offset (scrollTop) to the result of getBoundingClientRect().top.

On the other hand, if you have no idea which container in your element's parent tree is scrollable, or if your element has more than one scrollable parent, you can check your element's tree up to the top node, which is the <html> element, i.e. document.documentElement.

function getPageOffset(elem) {
  let topOffset = elem.getBoundingClientRect().top;

  while (elem != document.documentElement) {
    elem = elem.parentElement;
    topOffset += elem.scrollTop;
  }
  return topOffset;
}

Here is a simple example of a paragraph nested in a tree of three scrollable containers, which makes use of the above function (you may need to resize your browser's viewport for the scrollbars to appear):

var myElem = document.getElementById("myElem");

function getPageOffset(elem) {
  let topOffset = elem.getBoundingClientRect().top;

  while (elem != document.documentElement) {
    elem = elem.parentElement;
    topOffset += elem.scrollTop;
  }
  return topOffset;
}

document.getElementById("myBtn").addEventListener("click", function() {
  console.log(getPageOffset(myElem));
});
.parent1,
.parent2,
.parent3 {
  height: 100vh;
  overflow-y: auto;
}

.parent1 {
  height: 400px;
}

button {
  position: fixed;
  top:  20px;
  left: 20px;
}
<div class="parent1">
  <br/>
  <br/>
  <br/>
  <br/>
  <br/>
  <br/>
  <br/>
  <div class="parent2">
    <br/>
    <br/>
    <br/>
    <br/>
    <br/>
    <br/>
    <br/>
    <div class="parent3">
      <br/>
      <br/>
      <br/>
      <br/>
      <br/>
      <br/>
      <br/>
      <p id="myElem">This is the element I want to get the top offset of.</p>
    </div>
  </div>
</div>
<button id="myBtn">Get top offset</button>

There are negligible margins of error between the measurements (due to addition inaccuracies) which can be overe with some sort of rounding.

I may be missing something in your question, as I can see offsetTop works exactly the way you are intended to do so. Please refer https://stackblitz./edit/angular-rpaupe?file=src%2Fapp%2Fcdk-drag-drop-sorting-example.html.

It does updated it's offsetTop based on it's new position in a scrollable container.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744317029a4568233.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信