offsetTop vs. jQuery.offset().top
I think you are right by saying that people cannot click half pixels, so personally, I would use rounded jQuery offset...
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 scrolleddocElem.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 thedocumentviewport (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
. Addelement.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
. Addwindow.pageYOffset
if you want to take the document scrolling into account. You don't need to subtract document'sclientTop
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
Try this: parseInt(jQuery.offset().top, 10)