aboutsummaryrefslogtreecommitdiffstats
path: root/src/offset.js
diff options
context:
space:
mode:
authorRichard Gibson <richard.gibson@gmail.com>2017-04-24 12:15:39 -0400
committerGitHub <noreply@github.com>2017-04-24 12:15:39 -0400
commit1d2df772b4d6e5dbf91df6e75f4a1809f7879ab0 (patch)
tree96caec8d8d4c290a828d02c39a2b915bad5c5970 /src/offset.js
parente1b1b2d7fe5aff907a9accf59910bc3b7e4d1dec (diff)
downloadjquery-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.js57
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