Show More
Commit Description:
submission report
Commit Description:
submission report
References:
File last commit:
Show/Diff file:
Action:
node_modules/jquery/src/offset.js
| 233 lines
| 6.7 KiB
| application/javascript
| JavascriptLexer
|
r789 | define( [ | |||
"./core", | ||||
"./core/access", | ||||
"./var/document", | ||||
"./var/documentElement", | ||||
"./var/isFunction", | ||||
"./css/var/rnumnonpx", | ||||
"./css/curCSS", | ||||
"./css/addGetHookIf", | ||||
"./css/support", | ||||
"./var/isWindow", | ||||
"./core/init", | ||||
"./css", | ||||
"./selector" // contains | ||||
], function( jQuery, access, document, documentElement, isFunction, rnumnonpx, | ||||
curCSS, addGetHookIf, support, isWindow ) { | ||||
"use strict"; | ||||
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 ( 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() relates an element's border box to the document origin | ||||
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 rect, win, | ||||
elem = this[ 0 ]; | ||||
if ( !elem ) { | ||||
return; | ||||
} | ||||
// Return zeros for disconnected and hidden (display: none) elements (gh-2310) | ||||
// Support: IE <=11 only | ||||
// Running getBoundingClientRect on a | ||||
// disconnected node in IE throws an error | ||||
if ( !elem.getClientRects().length ) { | ||||
return { top: 0, left: 0 }; | ||||
} | ||||
// Get document-relative position by adding viewport scroll to viewport-relative gBCR | ||||
rect = elem.getBoundingClientRect(); | ||||
win = elem.ownerDocument.defaultView; | ||||
return { | ||||
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, doc, | ||||
elem = this[ 0 ], | ||||
parentOffset = { top: 0, left: 0 }; | ||||
// position:fixed elements are offset from the viewport, which itself always has zero offset | ||||
if ( jQuery.css( elem, "position" ) === "fixed" ) { | ||||
// Assume position:fixed implies availability of getBoundingClientRect | ||||
offset = elem.getBoundingClientRect(); | ||||
} else { | ||||
offset = this.offset(); | ||||
// 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" ) { | ||||
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 += jQuery.css( offsetParent, "borderTopWidth", true ); | ||||
parentOffset.left += jQuery.css( offsetParent, "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 ) { | ||||
// Coalesce documents and windows | ||||
var win; | ||||
if ( isWindow( elem ) ) { | ||||
win = elem; | ||||
} else if ( elem.nodeType === 9 ) { | ||||
win = elem.defaultView; | ||||
} | ||||
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; | ||||
} ); | ||||