Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
232 lines (190 sloc)
6.2 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| define( [ | |
| "./core", | |
| "./core/access", | |
| "./var/document", | |
| "./var/documentElement", | |
| "./css/var/rnumnonpx", | |
| "./css/curCSS", | |
| "./css/addGetHookIf", | |
| "./css/support", | |
| "./core/init", | |
| "./css", | |
| "./selector" // contains | |
| ], function( jQuery, access, document, documentElement, rnumnonpx, curCSS, addGetHookIf, support ) { | |
| "use strict"; | |
| /** | |
| * Gets a window from an element | |
| */ | |
| function getWindow( elem ) { | |
| return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView; | |
| } | |
| jQuery.offset = { | |
| setOffset: function( elem, options, i ) { | |
| var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, | |
| position = jQuery.css( elem, "position" ), | |
| curElem = jQuery( elem ), | |
| props = {}; | |
| // Set position first, in-case top/left are set even on static elem | |
| if ( position === "static" ) { | |
| elem.style.position = "relative"; | |
| } | |
| curOffset = curElem.offset(); | |
| curCSSTop = jQuery.css( elem, "top" ); | |
| curCSSLeft = jQuery.css( elem, "left" ); | |
| calculatePosition = ( position === "absolute" || position === "fixed" ) && | |
| ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; | |
| // Need to be able to calculate position if either | |
| // top or left is auto and position is either absolute or fixed | |
| if ( calculatePosition ) { | |
| curPosition = curElem.position(); | |
| curTop = curPosition.top; | |
| curLeft = curPosition.left; | |
| } else { | |
| curTop = parseFloat( curCSSTop ) || 0; | |
| curLeft = parseFloat( curCSSLeft ) || 0; | |
| } | |
| if ( jQuery.isFunction( options ) ) { | |
| // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) | |
| options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); | |
| } | |
| if ( options.top != null ) { | |
| props.top = ( options.top - curOffset.top ) + curTop; | |
| } | |
| if ( options.left != null ) { | |
| props.left = ( options.left - curOffset.left ) + curLeft; | |
| } | |
| if ( "using" in options ) { | |
| options.using.call( elem, props ); | |
| } else { | |
| curElem.css( props ); | |
| } | |
| } | |
| }; | |
| jQuery.fn.extend( { | |
| offset: function( options ) { | |
| // Preserve chaining for setter | |
| if ( arguments.length ) { | |
| return options === undefined ? | |
| this : | |
| this.each( function( i ) { | |
| jQuery.offset.setOffset( this, options, i ); | |
| } ); | |
| } | |
| var docElem, win, rect, doc, | |
| elem = this[ 0 ]; | |
| if ( !elem ) { | |
| return; | |
| } | |
| // Support: IE <=11 only | |
| // Running getBoundingClientRect on a | |
| // disconnected node in IE throws an error | |
| if ( !elem.getClientRects().length ) { | |
| return { top: 0, left: 0 }; | |
| } | |
| rect = elem.getBoundingClientRect(); | |
| // Make sure element is not hidden (display: none) | |
| if ( rect.width || rect.height ) { | |
| doc = elem.ownerDocument; | |
| win = getWindow( doc ); | |
| docElem = doc.documentElement; | |
| return { | |
| top: rect.top + win.pageYOffset - docElem.clientTop, | |
| left: rect.left + win.pageXOffset - docElem.clientLeft | |
| }; | |
| } | |
| // Return zeros for disconnected and hidden elements (gh-2310) | |
| return rect; | |
| }, | |
| position: function() { | |
| if ( !this[ 0 ] ) { | |
| return; | |
| } | |
| var offsetParent, offset, | |
| 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 | |
| if ( jQuery.css( elem, "position" ) === "fixed" ) { | |
| // Assume getBoundingClientRect is there when computed position is fixed | |
| offset = elem.getBoundingClientRect(); | |
| } else { | |
| // Get *real* offsetParent | |
| offsetParent = this.offsetParent(); | |
| // Get correct offsets | |
| offset = this.offset(); | |
| if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { | |
| parentOffset = offsetParent.offset(); | |
| } | |
| // 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 | |
| return { | |
| top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), | |
| left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) | |
| }; | |
| }, | |
| // This method will return documentElement in the following cases: | |
| // 1) For the element inside the iframe without offsetParent, this method will return | |
| // documentElement of the parent window | |
| // 2) For the hidden or detached element | |
| // 3) For body or html element, i.e. in case of the html node - it will return itself | |
| // | |
| // but those exceptions were never presented as a real life use-cases | |
| // and might be considered as more preferable results. | |
| // | |
| // This logic, however, is not guaranteed and can change at any point in the future | |
| offsetParent: function() { | |
| return this.map( function() { | |
| var offsetParent = this.offsetParent; | |
| while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { | |
| offsetParent = offsetParent.offsetParent; | |
| } | |
| return offsetParent || documentElement; | |
| } ); | |
| } | |
| } ); | |
| // Create scrollLeft and scrollTop methods | |
| jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { | |
| var top = "pageYOffset" === prop; | |
| jQuery.fn[ method ] = function( val ) { | |
| return access( this, function( elem, method, val ) { | |
| var win = getWindow( elem ); | |
| if ( val === undefined ) { | |
| return win ? win[ prop ] : elem[ method ]; | |
| } | |
| if ( win ) { | |
| win.scrollTo( | |
| !top ? val : win.pageXOffset, | |
| top ? val : win.pageYOffset | |
| ); | |
| } else { | |
| elem[ method ] = val; | |
| } | |
| }, method, val, arguments.length ); | |
| }; | |
| } ); | |
| // Support: Safari <=7 - 9.1, Chrome <=37 - 49 | |
| // Add the top/left cssHooks using jQuery.fn.position | |
| // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 | |
| // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 | |
| // getComputedStyle returns percent when specified for top/left/bottom/right; | |
| // rather than make the css module depend on the offset module, just check for it here | |
| jQuery.each( [ "top", "left" ], function( i, prop ) { | |
| jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, | |
| function( elem, computed ) { | |
| if ( computed ) { | |
| computed = curCSS( elem, prop ); | |
| // If curCSS returns percentage, fallback to offset | |
| return rnumnonpx.test( computed ) ? | |
| jQuery( elem ).position()[ prop ] + "px" : | |
| computed; | |
| } | |
| } | |
| ); | |
| } ); | |
| return jQuery; | |
| } ); |