如何获得元素相对于浏览器视口的顶部位置?

Wal*_*ssa 152 javascript

我想得到一个元素相对于浏览器视口的位置(显示页面的视口,而不是整个页面).如何在JavaScript中完成?

非常感谢

Him*_*u P 264

现有答案现已过时.本机getBoundingClientRect()方法已经存在了很长一段时间,并且正是问题所要求的.此外,它支持所有浏览器(包括IE 5,似乎!)

来自MDN页面:

返回的值是一个TextRectangle对象,它包含描述border-box的只读左,上,右和底属性,以像素为单位,左上角相对于视口的左上角.

你这样使用它:

var viewportOffset = el.getBoundingClientRect();
// these are relative to the viewport, i.e. the window
var top = viewportOffset.top;
var left = viewportOffset.left;
Run Code Online (Sandbox Code Playgroud)

  • 适用于大多数情况,但它假设元素不在嵌入式iframe中,对吧?问题是询问相关浏览器的窗口.el.getBoundingClientRect()将返回相对于iframe的窗口,而不是浏览器窗口. (4认同)
  • 问题是询问相关浏览器的窗口. (4认同)
  • 使用浏览器缩放(Android Chrome)时,这可能无法正常工作.来自@rism的解决方案([见下文](http://stackoverflow.com/a/1350681/2757230))适用于此案例 (2认同)
  • @Denilson`getBoundingClientRect()。top`不在我的IE11中,它返回0。 (2认同)
  • 你可以用 `const { top, left } = viewportOffset` 来简化它 (2认同)

Fab*_*sco 42

在我的情况下,为了安全滚动,我添加了window.scroll到等式:

var element = document.getElementById('myElement');
var topPos = element.getBoundingClientRect().top + window.scrollY;
var leftPos = element.getBoundingClientRect().left + window.scrollX;
Run Code Online (Sandbox Code Playgroud)

这使得我可以获得元素在文档上的真实相对位置,即使它已被滚动.

  • @Arif `window.scrollY || window.pageYOffset` 可能会改进支持 (4认同)
  • 你不是应该添加滚动位置而不是减去它吗? (2认同)

Der*_*ley 15

编辑: 添加一些代码以考虑页面滚动.

function findPos(id) {
    var node = document.getElementById(id);     
    var curtop = 0;
    var curtopscroll = 0;
    if (node.offsetParent) {
        do {
            curtop += node.offsetTop;
            curtopscroll += node.offsetParent ? node.offsetParent.scrollTop : 0;
        } while (node = node.offsetParent);

        alert(curtop - curtopscroll);
    }
}
Run Code Online (Sandbox Code Playgroud)

id参数是您想要的偏移量的元素的id.改编自quirksmode帖子.

  • 感谢您的回答,但我认为您误解了我的问题,我知道如何获得相对于页面的元素的顶部,我想要做的是获得相对于“视口”(即浏览器窗口)的位置, 不是文档) (2认同)

小智 10

var element =  document.querySelector('selector');
var bodyRect = document.body.getBoundingClientRect(),
    elemRect = element.getBoundingClientRect(),
    offset   = elemRect.top - bodyRect.top;
Run Code Online (Sandbox Code Playgroud)


jor*_*man 8

jQuery 非常优雅地实现了这一点。如果您查看 jQuery's 的源代码offset,您会发现这基本上是它的实现方式:

var rect = elem.getBoundingClientRect();
var win = elem.ownerDocument.defaultView;

return {
    top: rect.top + win.pageYOffset,
    left: rect.left + win.pageXOffset
};
Run Code Online (Sandbox Code Playgroud)


kar*_*bal 7

function inViewport(element) {
    let bounds = element.getBoundingClientRect();
    let viewWidth = document.documentElement.clientWidth;
    let viewHeight = document.documentElement.clientHeight;

    if (bounds['left'] < 0) return false;
    if (bounds['top'] < 0) return false;
    if (bounds['right'] > viewWidth) return false;
    if (bounds['bottom'] > viewHeight) return false;

    return true;
}
Run Code Online (Sandbox Code Playgroud)

来源


ris*_*ism 5

页面上的函数将返回一个矩形,其中包含传递的元素相对于浏览器视口的顶部、左侧、高度和宽度坐标。

    localToGlobal: function( _el ) {
       var target = _el,
       target_width = target.offsetWidth,
       target_height = target.offsetHeight,
       target_left = target.offsetLeft,
       target_top = target.offsetTop,
       gleft = 0,
       gtop = 0,
       rect = {};

       var moonwalk = function( _parent ) {
        if (!!_parent) {
            gleft += _parent.offsetLeft;
            gtop += _parent.offsetTop;
            moonwalk( _parent.offsetParent );
        } else {
            return rect = {
            top: target.offsetTop + gtop,
            left: target.offsetLeft + gleft,
            bottom: (target.offsetTop + gtop) + target_height,
            right: (target.offsetLeft + gleft) + target_width
            };
        }
    };
        moonwalk( target.offsetParent );
        return rect;
}
Run Code Online (Sandbox Code Playgroud)


Sze*_*eri 5

你可以试试:

node.offsetTop - window.scrollY

它适用于Opera,并定义了视口元标记.

  • 如果我理解[文档](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetTop),`offsetTop`是相对于最接近的定位元素.根据页面结构,可能是也可能不是根元素. (5认同)