diff --git a/src/offset.js b/src/offset.js index 381a42da2..6a2fdc993 100644 --- a/src/offset.js +++ b/src/offset.js @@ -107,33 +107,39 @@ jQuery.offset = { jQuery.fn.extend({ position: function() { - if ( !this[0] ) { + if ( !this[ 0 ] ) { return; } - var elem = this[0], + var offsetParent, offset, + parentOffset = { top: 0, left: 0 }, + elem = this[ 0 ]; - // Get *real* offsetParent - offsetParent = this.offsetParent(), + // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent + if ( jQuery.css( elem, "position" ) === "fixed" ) { + // we assume that getBoundingClientRect is available when computed position is fixed + offset = elem.getBoundingClientRect(); + } else { + // Get *real* offsetParent + offsetParent = this.offsetParent(); - // Get correct offsets - offset = this.offset(), - parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); + // Get correct offsets + offset = this.offset(); + if ( !rroot.test( offsetParent[ 0 ].nodeName ) ) { + parentOffset = offsetParent.offset(); + } - // Subtract element margins + // Add offsetParent borders + parentOffset.top += parseFloat( jQuery.css( offsetParent[ 0 ], "borderTopWidth" ) ) || 0; + parentOffset.left += parseFloat( jQuery.css( offsetParent[ 0 ], "borderLeftWidth" ) ) || 0; + } + + // Subtract parent offsets and element margins // note: when an element has margin: auto the offsetLeft and marginLeft // are the same in Safari causing offset.left to incorrectly be 0 - offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; - offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; - - // Add offsetParent borders - parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; - parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; - - // Subtract the two offsets return { - top: offset.top - parentOffset.top, - left: offset.left - parentOffset.left + top: offset.top - parentOffset.top - ( parseFloat( jQuery.css( elem, "marginTop" ) ) || 0 ), + left: offset.left - parentOffset.left - ( parseFloat( jQuery.css( elem, "marginLeft" ) ) || 0 ) }; }, diff --git a/test/unit/offset.js b/test/unit/offset.js index 7a1d719f0..b1cb0a3f5 100644 --- a/test/unit/offset.js +++ b/test/unit/offset.js @@ -1,6 +1,27 @@ if ( jQuery.fn.offset ) { -module("offset", { teardown: moduleTeardown }); +module("offset", { setup: function(){ + // force a scroll value on the main window + // this insures that the results will be wrong + // if the offset method is using the scroll offset + // of the parent window + var forceScroll = jQuery("