Commit cbe0c2ef authored by Oleg's avatar Oleg Committed by Dave Methvin

2.0: Reduce offset module. Close gh-1139.

parent 19def21d
...@@ -8,8 +8,8 @@ jQuery.fn.offset = function( options ) { ...@@ -8,8 +8,8 @@ jQuery.fn.offset = function( options ) {
} }
var docElem, win, var docElem, win,
box = { top: 0, left: 0 },
elem = this[ 0 ], elem = this[ 0 ],
box = { top: 0, left: 0 },
doc = elem && elem.ownerDocument; doc = elem && elem.ownerDocument;
if ( !doc ) { if ( !doc ) {
...@@ -30,33 +30,35 @@ jQuery.fn.offset = function( options ) { ...@@ -30,33 +30,35 @@ jQuery.fn.offset = function( options ) {
} }
win = getWindow( doc ); win = getWindow( doc );
return { return {
top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ), top: box.top + win.pageYOffset - docElem.clientTop,
left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 ) left: box.left + win.pageXOffset - docElem.clientLeft
}; };
}; };
jQuery.offset = { jQuery.offset = {
setOffset: function( elem, options, i ) { setOffset: function( elem, options, i ) {
var position = jQuery.css( elem, "position" ); 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 // Set position first, in-case top/left are set even on static elem
if ( position === "static" ) { if ( position === "static" ) {
elem.style.position = "relative"; elem.style.position = "relative";
} }
var curElem = jQuery( elem ), curOffset = curElem.offset();
curOffset = curElem.offset(), curCSSTop = jQuery.css( elem, "top" );
curCSSTop = jQuery.css( elem, "top" ), curCSSLeft = jQuery.css( elem, "left" );
curCSSLeft = jQuery.css( elem, "left" ), calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
props = {}, curPosition = {}, curTop, curLeft;
// need to be able to calculate position if either top or left is auto and position is either absolute or fixed // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
if ( calculatePosition ) { if ( calculatePosition ) {
curPosition = curElem.position(); curPosition = curElem.position();
curTop = curPosition.top; curTop = curPosition.top;
curLeft = curPosition.left; curLeft = curPosition.left;
} else { } else {
curTop = parseFloat( curCSSTop ) || 0; curTop = parseFloat( curCSSTop ) || 0;
curLeft = parseFloat( curCSSLeft ) || 0; curLeft = parseFloat( curCSSLeft ) || 0;
...@@ -75,6 +77,7 @@ jQuery.offset = { ...@@ -75,6 +77,7 @@ jQuery.offset = {
if ( "using" in options ) { if ( "using" in options ) {
options.using.call( elem, props ); options.using.call( elem, props );
} else { } else {
curElem.css( props ); curElem.css( props );
} }
...@@ -90,13 +93,14 @@ jQuery.fn.extend({ ...@@ -90,13 +93,14 @@ jQuery.fn.extend({
} }
var offsetParent, offset, var offsetParent, offset,
parentOffset = { top: 0, left: 0 }, elem = this[ 0 ],
elem = this[ 0 ]; parentOffset = { top: 0, left: 0 };
// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
if ( jQuery.css( elem, "position" ) === "fixed" ) { if ( jQuery.css( elem, "position" ) === "fixed" ) {
// we assume that getBoundingClientRect is available when computed position is fixed // We assume that getBoundingClientRect is available when computed position is fixed
offset = elem.getBoundingClientRect(); offset = elem.getBoundingClientRect();
} else { } else {
// Get *real* offsetParent // Get *real* offsetParent
offsetParent = this.offsetParent(); offsetParent = this.offsetParent();
...@@ -108,25 +112,25 @@ jQuery.fn.extend({ ...@@ -108,25 +112,25 @@ jQuery.fn.extend({
} }
// Add offsetParent borders // Add offsetParent borders
parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
} }
// Subtract parent offsets and element margins // Subtract parent offsets and element margins
// note: when an element has margin: auto the offsetLeft and marginLeft
// are the same in Safari causing offset.left to incorrectly be 0
return { return {
top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true) left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
}; };
}, },
offsetParent: function() { offsetParent: function() {
return this.map(function() { return this.map(function() {
var offsetParent = this.offsetParent || document.documentElement; var offsetParent = this.offsetParent || document.documentElement;
while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) { while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
offsetParent = offsetParent.offsetParent; offsetParent = offsetParent.offsetParent;
} }
return offsetParent || document.documentElement; return offsetParent || document.documentElement;
}); });
} }
...@@ -135,22 +139,20 @@ jQuery.fn.extend({ ...@@ -135,22 +139,20 @@ jQuery.fn.extend({
// Create scrollLeft and scrollTop methods // Create scrollLeft and scrollTop methods
jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
var top = /Y/.test( prop ); var top = "pageYOffset" === prop;
jQuery.fn[ method ] = function( val ) { jQuery.fn[ method ] = function( val ) {
return jQuery.access( this, function( elem, method, val ) { return jQuery.access( this, function( elem, method, val ) {
var win = getWindow( elem ); var win = getWindow( elem );
if ( val === undefined ) { if ( val === undefined ) {
return win ? (prop in win) ? win[ prop ] : return win ? win[ prop ] : elem[ method ];
win.document.documentElement[ method ] :
elem[ method ];
} }
if ( win ) { if ( win ) {
win.scrollTo( win.scrollTo(
!top ? val : jQuery( win ).scrollLeft(), !top ? val : window.pageXOffset,
top ? val : jQuery( win ).scrollTop() top ? val : window.pageYOffset
); );
} else { } else {
...@@ -161,9 +163,5 @@ jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( me ...@@ -161,9 +163,5 @@ jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( me
}); });
function getWindow( elem ) { function getWindow( elem ) {
return jQuery.isWindow( elem ) ? return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
elem :
elem.nodeType === 9 ?
elem.defaultView || elem.parentWindow :
false;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment