当身体相对定位时,如何计算dom元素的页面位置?

mck*_*oss 6 html javascript css

我有一个奇怪的错误,当我将主体设置为具有39px边距的相对定位元素时开始显示(我正在为页面顶部的工具栏腾出空间).

无论如何 - 如果你看一下大多数网站如何告诉你计算页面元素的位置,你会看到如下代码:

function getPos(elt) {
    var pt = [0, 0];

    while (elt.offsetParent !== null) {
        pt[0] += elt.offsetLeft;
        pt[1] += elt.offsetTop;
        elt = elt.offsetParent;
    }
    return pt;
}
Run Code Online (Sandbox Code Playgroud)

这很好,即使你的<body>标签有一个边距.但是,如果你的身体也是位置:相对,那么这会返回一个太小的值 - 它不包括body元素的边距.

我如何1)检测身体是否相对定位,2)找到我们的边距是什么,以便我可以将它们重新添加?

请注意,我需要Page坐标,因此我可以将它们与MouseEvent PageX,PageY进行比较.

mck*_*oss 14

如果你只限于在"现代"浏览器中工作,就像zepto.js实现那样,你可以得到一个小得多的.offset()函数实现:

offset: function(){
      var obj = this[0].getBoundingClientRect();
      return {
        left: obj.left + document.body.scrollLeft,
        top: obj.top + document.body.scrollTop,
        width: obj.width,
        height: obj.height
      };
    }
Run Code Online (Sandbox Code Playgroud)

https://github.com/madrobby/zepto/blob/master/src/zepto.js

如果getBoundingClientRect可用,那或多或少是jQuery所做的.


mck*_*oss 4

好的,我刚刚对此做了更多研究。简短的回答,使用 jQuery:

$(elt).offset()
Run Code Online (Sandbox Code Playgroud)

这是一个复杂的领域,jQuery 有大量代码来正确处理所有情况(请参阅https://github.com/jquery/jquery/blob/master/src/offset.js)。我认为大多数浏览器都支持 getClientBoundingRect - 在这种情况下 jQuery 将使用它(但必须调整视口滚动位置)。否则,它会调整正文的计算样式(是的, $(elt).css('margin-left') 将返回计算样式)以及中间元素上的任何边框。

所以,长的答案是 - 除非你想从 jQuery 或其他框架重新发明 100 多行代码 - 最好使用他们的代码来获得这个测量,而不是编写你自己的代码。

这是一个小提琴手展示了一些其他方法(从 Snake Faust 的扩展 - 谢谢!):

http://jsfiddle.net/mckoss/9zLGt/

顺便说一句,Snake,与父容器的偏移量是 $(elt).position(); $(elt).offset() 返回相对于页面/文档的偏移量 - 这就是我在这里寻找的。