如何获取绝对定位元素的左/右/上/下实际值?

10

(这似乎是一个简单的问题,以前可能已经有人问过了,但如果有的话我找不到,尽管有很多类似的问题没有回答我想要的。)

在Firefox(24.0)中,这段代码给我我想要的内容-相关像素数:

jQuery('selector').css('right')

在Chrome(34.0.1847.137 m)中,只有left/top返回像素值,但是right/bottom返回auto
在Stack Overflow上,有许多关于这是.css的预期行为的问题,但我找不到任何解释如何获得我想要的行为的内容-即给我计算后的所有四个值。
JS或jQuery是否有直接获取这四个值的方法,在所有浏览器/场景中都能正常工作? (还是必须采用丑陋的手动计算?)
澄清一下:我需要的值与Firefox返回的.css('right')值相同-这是当前和父元素右侧边缘之间的距离。 这与某些函数返回的基于视口的左侧+宽度定义不同。
即这里记录的值应数字上相同:
elem = jQuery('selector')
rect = someFunction( elem[0] );
console.log([ elem.css('left') , rect.left ]);
console.log([ elem.css('right') , rect.right ]);
console.log([ elem.css('top') , rect.top ]);
console.log([ elem.css('bottom') , rect.bottom ]);

除非我误读了其他答案,否则只有kalley的getRelativeClientRect答案符合此标准。


你不能只是将宽度和高度添加到左侧和顶部的值吗? - Pointy
不行,因为.css('right')是相对于父元素最右边缘的像素数,这与left+width不同。 - Peter Boughton
啊,好的,我明白你的意思了。 - Pointy
5个回答

14

你可以使用getBoundingClientRect。如果你正在使用变换,它也会考虑到它们。

你需要像这样调用它:jQuery('选择器')[0].getBoundingClientRect()。或者使用纯JavaScript,像这样:document.querySelector('选择器').getBoundingClientRect(),它将返回单个元素或 document.querySelectorAll('选择器')[索引值].getBoundingClientRect()

简而言之,在稍微易读的格式中:

  • jQuery('选择器')[0].getBoundingClientRect()
  • document.querySelector('选择器').getBoundingClientRect()
  • document.querySelectorAll('选择器')[索引值].getBoundingClientRect()

或者用旧的方法替换 QS 调用,如 getElementById 等。

以下是一个函数,如果你想相对于其父元素获取它,就可以使用它:

function getRelativeClientRect(el) {
  var rect = el.getBoundingClientRect(),
      parentRect = el.offsetParent.getBoundingClientRect();
  return {
    bottom: parentRect.bottom - rect.bottom,
    height: rect.height,
    left: rect.left - parentRect.left,
    right: parentRect.right - rect.right,
    top: rect.top - parentRect.top,
    width: rect.width
  };
}

哦,太棒了!我猜我对原帖的评论是不准确的。 - Cerbrus
2
值得注意的是,getBoundingClientRect返回一些矩形,其中lefttop相对于视口的,因此它当然是不同的东西。使用它还需要所谓的丑陋手动计算 - King King
1
增加了一个功能,该功能将根据您元素的offsetParent来标准化所有内容。感谢@KingKing指出仅使用此功能的缺陷。 - kalley
2
左边和顶部返回了负值(我修复了顺序),但我想现在这可能是最好的选择。 - Peter Boughton
1
@PeterBoughton 我在我的网站上使用这个函数,但遇到了一些奇怪的问题。当在一个时间间隔内运行时,当用户切换到不同的浏览器选项卡时,此函数似乎会返回不同的值。 请看一下我的这个问题:http://stackoverflow.com/questions/28842302/webpage-javascript-behaves-differently-when-the-view-is-switched-to-other-browse - shenkwen

1

编辑:这是关于 绝对定位 的内容

非常古老的函数 findPos

http://www.quirksmode.org/js/findpos.html

变量考虑滚动条和边框
function getPosition(el){
 var x=0,y= 0;
 while(el) {
  x+=(el.offsetLeft-el.scrollLeft+el.clientLeft);
  y+=(el.offsetTop-el.scrollTop+el.clientTop);
  el=el.offsetParent;
 }
 return{x:x,y:y}
}

获取正确的结果

  var info=getPosition(element);
  console.log('marginRight: '+info.x-element.offsetWidth);

注意1:这些是纯JavaScript函数,与旧版浏览器兼容。因此不需要jQuery。显然,性能比使用jQuery要好得多。
注意2:如果搜索“查找位置”,还有许多其他版本可用。
getBoundingClientRect
获取正确的位置
  var info=element.getBoundingClientRect(); // Native Javascript ..think 1.6+
  console.log('marginRight: 'info.right-info.width);

结论

如果你想要一个全面兼容的脚本来获取元素的尺寸、偏移和应用的css,那么没有简单的方法。

getPosition函数可能是最好的函数(考虑到兼容性),它可以轻松地计算这些值。

注意:由于函数内部有一个while循环,在非常旧的机器上,您可能会遇到一些与嵌套元素相关的问题。

如果您使用的是html5和css,则可以使用getBoundingClientRect

注意:当使用css3变换时,两者可能都会出现问题。

编辑

我需要与Firefox返回的.css('right')值等效的值

要获取这些值,您首先需要找到元素的位置。

所以:getPosition函数或getBoundingClientRect

然后您需要计算顶部/底部、左侧/右侧的值。

left=x
right=x-width
top=y
bottom=y-height

编辑2:

如果只想应用到父元素,您需要在父元素上执行getPosition,并且计算方法在@kalley的答案中显示。


1

在Javascript中有一种内置的方法可以实现这个功能,无需使用JQUERY。我将向您展示两种特殊的方法,一种是JS和CSS,另一种只是JS。

element.style.left; //Gives you distance from left edge of your viewport.
element.style.top + "px"; //Gives you distance in pixels from top edge
element.style.right; //etc.


//There is also the way of Offset. You do not need CSS at all for this.
//Of course, Jquery has its own way of doing this, but I'll show JS-only
element.offsetTop; //Gives distance from top of viewport to top of element
element.offsetLeft; //Gives distance from left of viewport to left of element
//etc.

一如既往,有许多使用和不使用Jquery的方法。我更喜欢完全不使用Jquery(尽管它很棒),我知道其他人也喜欢不使用Jquery。如果您想使用Jquery,我建议像@farincz那样使用Jquery方式。如果不想使用Jquery,则此方法或getBoundingClientRect更好。使用.style.top.style.left的最好之处在于您不仅可以获取left/right/top/bottom的实际值,还可以设置它们。这对于拖放等操作非常有用。


请注意,偏移量可以用于获取比样式更精确的左/上/右/下值,并且请注意,样式(CSS)通常用于设置这些值。样式非常适合移动项目的位置。 - Cannicide

0

您可以使用 $().offset 获取元素在文档中的位置。

假设 p 是您的元素相对于其定位的父元素。

那么左侧是

var left = $(el).offset().left - $(p).offset().left;

右侧更复杂,您必须同时使用宽度

var right = ($(p).offset().left + $(p).width()) - ($(el).offset().left + $(el).width());

最后一件事是获取 p 元素。你可以直接知道它,或者在 $(el).parents() 中找到它。 它具有相对或绝对定位。

如果我要计算它,这就是退步了,因为只需使用.getBoundingClientRect()即可提供底部/右侧,但它是相对于视口的。 (而我想要相当于从容器的右边缘测量的.css('right')。) - Peter Boughton

0
使用函数getBoundingClientRect(),它会给你左、右、上、下、宽度、高度的值:
var myid=document.getElementById("id").getBoundingClientRect();
var bottom=myid.bottom;
var top=myid.top;
var right=myid.right

...等等。

来源:MDN | Element.getBoundingClientRect()

编辑:

要获取相对于页面而不是视口的坐标:

var bodycoord=document.body.getBoundingClientRect();
    var top-from-page=myid.top-bodycoord.top;
    var left-from-page=myid.left-bodycoord.top;

它所提供的值不同 - 请参见King King的评论对于此方法的现有建议。 - Peter Boughton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接