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

时间:2009-08-29 05:44:55

标签: javascript

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

非常感谢

12 个答案:

答案 0 :(得分:234)

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

来自MDN page

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

你这样使用它:

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

答案 1 :(得分:33)

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

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

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

答案 2 :(得分: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);
    }
}

id参数是您想要的偏移量的元素的id。改编自quirksmode post

答案 3 :(得分:6)

您可以尝试:

node.offsetTop - window.scrollY

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

答案 4 :(得分:6)

var element =  document.querySelector('selector');
var bodyRect = document.body.getBoundingClientRect(),
    elemRect = element.getBoundingClientRect(),
    offset   = elemRect.top - bodyRect.top;

答案 5 :(得分:6)

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;
}

source

答案 6 :(得分:3)

jQuery非常优雅地实现了这一点。如果你看一下jQuery offset的来源,你会发现这基本上是它的实现方式:

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

return {
    top: rect.top + win.pageYOffset,
    left: rect.left + win.pageXOffset
};

答案 7 :(得分:2)

有时,getBoundingClientRect()对象的属性值对IE显示为0。在这种情况下,您必须为元素设置display = 'block'。您可以使用以下代码为所有浏览器获取偏移量。

扩展jQuery功能:

(function($) {
    jQuery.fn.weOffset = function () {
        var de = document.documentElement;
        $(this).css("display", "block");
        var box = $(this).get(0).getBoundingClientRect();
        var top = box.top + window.pageYOffset - de.clientTop;
        var left = box.left + window.pageXOffset - de.clientLeft;
        return { top: top, left: left };
    };
}(jQuery));

使用:

var elementOffset = $("#" + elementId).weOffset();

答案 8 :(得分:1)

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

    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;
}

答案 9 :(得分:1)

感谢所有答案。似乎Prototype已经有一个执行此操作的函数(page()函数)。通过查看函数的源代码,我发现它首先计算相对于页面的元素偏移位置(即文档顶部),然后从中减去scrollTop。有关更多详细信息,请参阅原型的源代码。

答案 10 :(得分:1)

我假设网页中存在id为btn1的元素,并且还包含jQuery。这适用于Chrome,FireFox,IE&gt; = 9和Edge的所有现代浏览器。 jQuery仅用于确定相对于文档的位置。

var screenRelativeTop =  $("#btn1").offset().top - (window.scrollY || 
                                            window.pageYOffset || document.body.scrollTop);

var screenRelativeLeft =  $("#btn1").offset().left - (window.scrollX ||
                                           window.pageXOffset || document.body.scrollLeft);

答案 11 :(得分:-1)

这种方式也适用于在JAVA中调用:

      Object bound = driver.executeScript("var bounding = arguments[0].getBoundingClientRect();" +
      "return bounding.top >= 0 && " +
      "        bounding.left >= 0 && " +
      "        bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) && " +
      "        bounding.right <= (window.innerWidth || document.documentElement.clientWidth)",
    element);

  boolean isElementInView = ((Boolean)bound).booleanValue(); //returns true if element in viewport