与 jQuery.offrey.top() . top

我已经读到,offsetLeftoffsetTop不能在所有的浏览器正常工作。jQuery.offset()应该为此提供一个抽象,以提供正确的值 x 浏览器。

我要做的是获取一个元素相对于该元素左上角被单击的位置的坐标。

问题是 jQuery.offset().top实际上在 FFX 3.6中给了我一个十进制值(在 IE 和 Chrome 中,这两个值是匹配的)。

这个小提琴 展示了这个问题。如果你点击底部图像,jQuery.offset().top返回327.5,但是 offsetTop返回328。

我认为 offset()正在返回正确的值,我应该使用它,因为它可以跨浏览器工作。然而,人们显然不能点击像素的小数。确定到 Math.round()的真偏移量的正确方法是否是 jQuery 返回的偏移量?我应该使用 offsetTop代替,还是完全使用其他方法?

254464 次浏览

I think you are right by saying that people cannot click half pixels, so personally, I would use rounded jQuery offset...

You can use parseInt(jQuery.offset().top) to always use the Integer (primitive - int) value across all browsers.

It is possible that the offset could be a non-integer, using em as the measurement unit, relative font-sizes in %.

I also theorise that the offset might not be a whole number when the zoom isn't 100% but that depends how the browser handles scaling.

Try this: parseInt(jQuery.offset().top, 10)

This is what jQuery API Doc says about .offset():

Get the current coordinates of the first element, or set the coordinates of every element, in the set of matched elements, relative to the document.

This is what MDN Web API says about .offsetTop:

offsetTop returns the distance of the current element relative to the top of the offsetParent node

This is what jQuery v.1.11 .offset() basically do when getting the coords:

var box = { top: 0, left: 0 };


// BlackBerry 5, iOS 3 (original iPhone)
if ( typeof elem.getBoundingClientRect !== strundefined ) {
box = elem.getBoundingClientRect();
}
win = getWindow( doc );
return {
top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
};
  • pageYOffset intuitively says how much was the page scrolled
  • docElem.scrollTop is the fallback for IE<9 (which are BTW unsupported in jQuery 2)
  • docElem.clientTop is the width of the top border of an element (the document in this case)
  • elem.getBoundingClientRect() gets the coords relative to the document viewport (see comments). It may return fraction values, so this is the source of your bug. It also may cause a bug in IE<8 when the page is zoomed. To avoid fraction values, try to calculate the position iteratively

Conclusion

  • If you want coords relative to the parent node, use element.offsetTop. Add element.scrollTop if you want to take the parent scrolling into account. (or use jQuery .position() if you are fan of that library)
  • If you want coords relative to the viewport use element.getBoundingClientRect().top. Add window.pageYOffset if you want to take the document scrolling into account. You don't need to subtract document's clientTop if the document has no border (usually it doesn't), so you have position relative to the document
  • Subtract element.clientTop if you don't consider the element border as the part of the element