diff options
author | Richard Gibson <richard.gibson@gmail.com> | 2017-04-24 12:15:39 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-24 12:15:39 -0400 |
commit | 1d2df772b4d6e5dbf91df6e75f4a1809f7879ab0 (patch) | |
tree | 96caec8d8d4c290a828d02c39a2b915bad5c5970 /src/offset.js | |
parent | e1b1b2d7fe5aff907a9accf59910bc3b7e4d1dec (diff) | |
download | jquery-1d2df772b4d6e5dbf91df6e75f4a1809f7879ab0.tar.gz jquery-1d2df772b4d6e5dbf91df6e75f4a1809f7879ab0.zip |
Offset: Use correct offset parents; include all border/scroll values
Thanks @anseki
Fixes gh-3080
Fixes gh-3107
Closes gh-3096
Closes gh-3487
Diffstat (limited to 'src/offset.js')
-rw-r--r-- | src/offset.js | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/src/offset.js b/src/offset.js index c1ab85787..563c6e8cd 100644 --- a/src/offset.js +++ b/src/offset.js @@ -7,13 +7,12 @@ define( [ "./css/curCSS", "./css/addGetHookIf", "./css/support", - "./core/nodeName", "./core/init", "./css", "./selector" // contains ], function( jQuery, access, document, documentElement, rnumnonpx, - curCSS, addGetHookIf, support, nodeName ) { + curCSS, addGetHookIf, support ) { "use strict"; @@ -70,6 +69,8 @@ jQuery.offset = { }; jQuery.fn.extend( { + + // offset() relates an element's border box to the document origin offset: function( options ) { // Preserve chaining for setter @@ -81,7 +82,7 @@ jQuery.fn.extend( { } ); } - var doc, docElem, rect, win, + var rect, win, elem = this[ 0 ]; if ( !elem ) { @@ -96,50 +97,54 @@ jQuery.fn.extend( { return { top: 0, left: 0 }; } + // Get document-relative position by adding viewport scroll to viewport-relative gBCR rect = elem.getBoundingClientRect(); - - doc = elem.ownerDocument; - docElem = doc.documentElement; - win = doc.defaultView; - + win = elem.ownerDocument.defaultView; return { - top: rect.top + win.pageYOffset - docElem.clientTop, - left: rect.left + win.pageXOffset - docElem.clientLeft + top: rect.top + win.pageYOffset, + left: rect.left + win.pageXOffset }; }, + // position() relates an element's margin box to its offset parent's padding box + // This corresponds to the behavior of CSS absolute positioning position: function() { if ( !this[ 0 ] ) { return; } - var offsetParent, offset, + var offsetParent, offset, doc, elem = this[ 0 ], parentOffset = { top: 0, left: 0 }; - // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, - // because it is its only offset parent + // position:fixed elements are offset from the viewport, which itself always has zero offset if ( jQuery.css( elem, "position" ) === "fixed" ) { - // Assume getBoundingClientRect is there when computed position is fixed + // Assume position:fixed implies availability of getBoundingClientRect offset = elem.getBoundingClientRect(); } else { + offset = this.offset(); - // Get *real* offsetParent - offsetParent = this.offsetParent(); + // Account for the *real* offset parent, which can be the document or its root element + // when a statically positioned element is identified + doc = elem.ownerDocument; + offsetParent = elem.offsetParent || doc.documentElement; + while ( offsetParent && + ( offsetParent === doc.body || offsetParent === doc.documentElement ) && + jQuery.css( offsetParent, "position" ) === "static" ) { - // Get correct offsets - offset = this.offset(); - if ( !nodeName( offsetParent[ 0 ], "html" ) ) { - parentOffset = offsetParent.offset(); + offsetParent = offsetParent.parentNode; + } + if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { + + // Incorporate borders into its offset, since they are outside its content origin + parentOffset = jQuery( offsetParent ).offset(); + parentOffset = { + top: parentOffset.top + jQuery.css( offsetParent, "borderTopWidth", true ), + left: parentOffset.left + jQuery.css( offsetParent, "borderLeftWidth", true ) + }; } - - // Add offsetParent borders - parentOffset = { - top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ), - left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ) - }; } // Subtract parent offsets and element margins |