获取元素相对于具有溢出的页面的位置
获取元素相对于具有溢出的页面的位置
我想获取一个元素相对于整个页面的位置,但该元素位于一个可滚动的容器中,这使得通常使用的方法变得无用。(指的是getBoundingClientRect()
,offsetTop
等)\n以我所指的内容为例:\nhttps://material.angular.io/cdk/drag-drop/overview\n在“基本拖放”部分,如果在不滚动页面的情况下获取元素的Y位置,element.getBoundingClientRect().top
会得到626的值。\n\n现在,如果向下滚动,使得元素几乎接触到窗口顶部,同样的元素会得到70的值。\n\n但是我想要的是相对于整个页面的完全相同的值,所以在滚动后值不应该改变。我知道对于默认的滚动行为,这将是成立的,但在这种情况下,不是body滚动,而是它的元素。
获取元素相对于页面的位置,是一个常见的需求。通常我们可以使用元素的`offsetTop`属性来获取元素相对于其offsetParent的上边缘的距离。但是,当元素有滚动容器,并且元素是可拖动的时候,`offsetTop`属性可能无法正确地获取元素的位置。
在这种情况下,元素的`offsetTop`属性不会随着元素在滚动容器中的新位置而更新。这是因为`offsetTop`属性只受到元素的布局属性的影响,而不受到`transform`属性的影响。在给定的示例中,当元素被拖动时,其`transform`属性会发生变化,但`offsetTop`属性不会受到这些`transform`变化的影响。
解决这个问题的方法是使用`getBoundingClientRect()`方法来获取元素的位置。这个方法返回一个DOMRect对象,其中包含了元素的位置、大小等信息。具体来说,我们可以使用`getBoundingClientRect().top`属性来获取元素相对于可视窗口的上边缘的距离,然后再加上滚动容器的滚动距离,就可以得到元素相对于页面的位置。
下面是一个示例代码,展示了如何使用`getBoundingClientRect()`方法来获取元素相对于页面的位置:
function getElementPosition(element) { const rect = element.getBoundingClientRect(); const scrollTop = window.pageYOffset || document.documentElement.scrollTop; const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; const top = rect.top + scrollTop; const left = rect.left + scrollLeft; return { top, left }; } const element = document.getElementById('my-element'); const position = getElementPosition(element); console.log(position);
通过以上方法,我们就可以正确地获取元素相对于页面的位置了,无论元素是否在滚动容器中,并且无论元素是否可拖动。
希望以上内容对您有所帮助!
从上述内容中,可以整理出问题的原因是要获取元素相对于页面的位置,但是页面中存在多个滚动容器,不知道要获取的元素位于哪个滚动容器中。解决方法是通过检查元素的父树,直到顶级节点,即元素,来获取页面偏移量。
具体的解决方法如下所示:
function getPageOffset(elem) { let topOffset = elem.getBoundingClientRect().top; while (elem != document.documentElement) { elem = elem.parentElement; topOffset += elem.scrollTop; } return topOffset; }
上述方法通过循环遍历元素的父节点,累加每个父节点的scrollTop值,来计算元素相对于页面的偏移量。
文章的完整内容如下:
如果您能确定包含元素的可滚动容器,只需将其垂直滚动偏移量(scrollTop)添加到getBoundingClientRect().top的结果即可。
另一方面,如果您不知道元素的父树中的哪个容器是可滚动的,或者如果您的元素具有多个可滚动的父级,则可以检查元素的树直到顶级节点,即元素,即document.documentElement。
以下是一个简单的示例,其中包含了一个嵌套在三个可滚动容器树中的段落,并使用了上述函数(您可能需要调整浏览器的视口大小以使滚动条出现):
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; }
This is the element I want to get the top offset of.
以上是这个问题的出现的原因以及解决方法。