1 import { jQuery } from "./core.js";
2 import { access } from "./core/access.js";
3 import { documentElement } from "./var/documentElement.js";
4 import { isWindow } from "./var/isWindow.js";
6 import "./core/init.js";
10 setOffset: function( elem, options, i ) {
11 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
12 position = jQuery.css( elem, "position" ),
13 curElem = jQuery( elem ),
16 // Set position first, in-case top/left are set even on static elem
17 if ( position === "static" ) {
18 elem.style.position = "relative";
21 curOffset = curElem.offset();
22 curCSSTop = jQuery.css( elem, "top" );
23 curCSSLeft = jQuery.css( elem, "left" );
24 calculatePosition = ( position === "absolute" || position === "fixed" ) &&
25 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
27 // Need to be able to calculate position if either
28 // top or left is auto and position is either absolute or fixed
29 if ( calculatePosition ) {
30 curPosition = curElem.position();
31 curTop = curPosition.top;
32 curLeft = curPosition.left;
35 curTop = parseFloat( curCSSTop ) || 0;
36 curLeft = parseFloat( curCSSLeft ) || 0;
39 if ( typeof options === "function" ) {
41 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
42 options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
45 if ( options.top != null ) {
46 props.top = ( options.top - curOffset.top ) + curTop;
48 if ( options.left != null ) {
49 props.left = ( options.left - curOffset.left ) + curLeft;
52 if ( "using" in options ) {
53 options.using.call( elem, props );
63 // offset() relates an element's border box to the document origin
64 offset: function( options ) {
66 // Preserve chaining for setter
67 if ( arguments.length ) {
68 return options === undefined ?
70 this.each( function( i ) {
71 jQuery.offset.setOffset( this, options, i );
82 // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
84 // Running getBoundingClientRect on a
85 // disconnected node in IE throws an error
86 if ( !elem.getClientRects().length ) {
87 return { top: 0, left: 0 };
90 // Get document-relative position by adding viewport scroll to viewport-relative gBCR
91 rect = elem.getBoundingClientRect();
92 win = elem.ownerDocument.defaultView;
94 top: rect.top + win.pageYOffset,
95 left: rect.left + win.pageXOffset
99 // position() relates an element's margin box to its offset parent's padding box
100 // This corresponds to the behavior of CSS absolute positioning
101 position: function() {
106 var offsetParent, offset, doc,
108 parentOffset = { top: 0, left: 0 };
110 // position:fixed elements are offset from the viewport, which itself always has zero offset
111 if ( jQuery.css( elem, "position" ) === "fixed" ) {
113 // Assume position:fixed implies availability of getBoundingClientRect
114 offset = elem.getBoundingClientRect();
117 offset = this.offset();
119 // Account for the *real* offset parent, which can be the document or its root element
120 // when a statically positioned element is identified
121 doc = elem.ownerDocument;
122 offsetParent = elem.offsetParent || doc.documentElement;
123 while ( offsetParent &&
124 offsetParent !== doc.documentElement &&
125 jQuery.css( offsetParent, "position" ) === "static" ) {
127 offsetParent = offsetParent.offsetParent || doc.documentElement;
129 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 &&
130 jQuery.css( offsetParent, "position" ) !== "static" ) {
132 // Incorporate borders into its offset, since they are outside its content origin
133 parentOffset = jQuery( offsetParent ).offset();
134 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
135 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
139 // Subtract parent offsets and element margins
141 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
142 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
146 // This method will return documentElement in the following cases:
147 // 1) For the element inside the iframe without offsetParent, this method will return
148 // documentElement of the parent window
149 // 2) For the hidden or detached element
150 // 3) For body or html element, i.e. in case of the html node - it will return itself
152 // but those exceptions were never presented as a real life use-cases
153 // and might be considered as more preferable results.
155 // This logic, however, is not guaranteed and can change at any point in the future
156 offsetParent: function() {
157 return this.map( function() {
158 var offsetParent = this.offsetParent;
160 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
161 offsetParent = offsetParent.offsetParent;
164 return offsetParent || documentElement;
169 // Create scrollLeft and scrollTop methods
170 jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
171 var top = "pageYOffset" === prop;
173 jQuery.fn[ method ] = function( val ) {
174 return access( this, function( elem, method, val ) {
176 // Coalesce documents and windows
178 if ( isWindow( elem ) ) {
180 } else if ( elem.nodeType === 9 ) {
181 win = elem.defaultView;
184 if ( val === undefined ) {
185 return win ? win[ prop ] : elem[ method ];
190 !top ? val : win.pageXOffset,
191 top ? val : win.pageYOffset
195 elem[ method ] = val;
197 }, method, val, arguments.length );
201 export { jQuery, jQuery as $ };