From: Rick Waldron Date: Tue, 20 Sep 2011 01:03:41 +0000 (-0400) Subject: Landing pull request 477. 1.7 jQuery.offset.supportsFixedPosition. Fixes #6809. X-Git-Tag: 1.7b1~30 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f60213648cefa9b53289ad01a55ead22a15e6ee1;p=jquery.git Landing pull request 477. 1.7 jQuery.offset.supportsFixedPosition. Fixes #6809. More Details: - https://github.com/jquery/jquery/pull/477 - http://bugs.jquery.com/ticket/6809 --- diff --git a/src/offset.js b/src/offset.js index 31f2503a4..4cc87acff 100644 --- a/src/offset.js +++ b/src/offset.js @@ -63,8 +63,6 @@ if ( "getBoundingClientRect" in document.documentElement ) { return jQuery.offset.bodyOffset( elem ); } - jQuery.offset.initialize(); - var computedStyle, offsetParent = elem.offsetParent, prevOffsetParent = elem, @@ -120,46 +118,22 @@ if ( "getBoundingClientRect" in document.documentElement ) { }; } -jQuery.offset = { - initialize: function() { - var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0, - html = "
"; - - jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } ); - - container.innerHTML = html; - body.insertBefore( container, body.firstChild ); - innerDiv = container.firstChild; - checkDiv = innerDiv.firstChild; - td = innerDiv.nextSibling.firstChild.firstChild; - - this.doesNotAddBorder = (checkDiv.offsetTop !== 5); - this.doesAddBorderForTableAndCells = (td.offsetTop === 5); - - checkDiv.style.position = "fixed"; - checkDiv.style.top = "20px"; - - // safari subtracts parent border width here which is 5px - this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15); - checkDiv.style.position = checkDiv.style.top = ""; +jQuery.offset = {}; - innerDiv.style.overflow = "hidden"; - innerDiv.style.position = "relative"; +jQuery.each( + ( "doesAddBorderForTableAndCells doesNotAddBorder " + + "doesNotIncludeMarginInBodyOffset subtractsBorderForOverflowNotVisible " + + "supportsFixedPosition" ).split(" "), function( i, prop ) { - this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5); - - this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop); + jQuery.offset[ prop ] = jQuery.support[ prop ]; +}); - body.removeChild( container ); - jQuery.offset.initialize = jQuery.noop; - }, +jQuery.extend( jQuery.offset, { bodyOffset: function( body ) { var top = body.offsetTop, left = body.offsetLeft; - jQuery.offset.initialize(); - if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) { top += parseFloat( jQuery.css(body, "marginTop") ) || 0; left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; @@ -210,10 +184,11 @@ jQuery.offset = { curElem.css( props ); } } -}; +}); jQuery.fn.extend({ + position: function() { if ( !this[0] ) { return null; diff --git a/src/support.js b/src/support.js index ad1bd9a57..fb730dca7 100644 --- a/src/support.js +++ b/src/support.js @@ -20,7 +20,8 @@ jQuery.support = (function() { events, eventName, i, - isSupported; + isSupported, + offsetSupport; // Preliminary tests div.setAttribute("className", "t"); @@ -249,6 +250,49 @@ jQuery.support = (function() { } } + // Determine fixed-position support early + offsetSupport = (function( body, container ) { + + var outer, inner, table, td, supports, + bodyMarginTop = parseFloat( body.style.marginTop ) || 0, + ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;", + style = "style='" + ptlm + "margin:0;border:5px solid #000;padding:0;'", + html = "
" + + "" + + "
"; + + container.style.cssText = ptlm + "border:0;visibility:hidden"; + + container.innerHTML = html; + body.insertBefore( container, body.firstChild ); + outer = container.firstChild; + inner = outer.firstChild; + td = outer.nextSibling.firstChild.firstChild; + + supports = { + doesNotAddBorder: (inner.offsetTop !== 5), + doesAddBorderForTableAndCells: (td.offsetTop === 5) + } + + inner.style.position = "fixed"; + inner.style.top = "20px"; + + // safari subtracts parent border width here which is 5px + supports.supportsFixedPosition = (inner.offsetTop === 20 || inner.offsetTop === 15); + inner.style.position = inner.style.top = ""; + + outer.style.overflow = "hidden"; + outer.style.position = "relative"; + + supports.subtractsBorderForOverflowNotVisible = (inner.offsetTop === -5); + supports.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop); + + return supports; + + })( testElement, div ); + + jQuery.extend( support, offsetSupport ); + // Null connected elements to avoid leaks in IE testElement = fragment = select = opt = body = marginDiv = div = input = null; diff --git a/test/unit/offset.js b/test/unit/offset.js index 79a0f3606..adb8a9eca 100644 --- a/test/unit/offset.js +++ b/test/unit/offset.js @@ -267,8 +267,6 @@ testoffset("static", function( jQuery ) { testoffset("fixed", function( jQuery ) { expect(30); - jQuery.offset.initialize(); - var tests = [ { id: "#fixed-1", top: 1001, left: 1001 }, { id: "#fixed-2", top: 1021, left: 1021 } @@ -403,8 +401,8 @@ testoffset("scroll", function( jQuery, win ) { testoffset("body", function( jQuery ) { expect(2); - equals( jQuery("body").offset().top, 1, "jQuery('#body').offset().top" ); - equals( jQuery("body").offset().left, 1, "jQuery('#body').offset().left" ); + equals( jQuery("body").offset().top, 0, "jQuery('#body').offset().top" ); + equals( jQuery("body").offset().left, 0, "jQuery('#body').offset().left" ); }); test("Chaining offset(coords) returns jQuery object", function() {