Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

offset is now a setter

  • Loading branch information...
commit daffb954e397bd5d9f8e9aaedab6c0baa9609e1e 1 parent f55fb36
Brandon Aaron brandonaaron authored
43 src/offset.js
View
@@ -1,7 +1,12 @@
if ( "getBoundingClientRect" in document.documentElement ) {
- jQuery.fn.offset = function() {
+ jQuery.fn.offset = function( options ) {
var elem = this[0];
if ( !elem || !elem.ownerDocument ) { return null; }
+ if ( options ) {
+ return this.each(function() {
+ jQuery.offset.setOffset( this, options );
+ });
+ }
if ( elem === elem.ownerDocument.body ) {
return jQuery.offset.bodyOffset( elem );
}
@@ -13,9 +18,14 @@ if ( "getBoundingClientRect" in document.documentElement ) {
return { top: top, left: left };
};
} else {
- jQuery.fn.offset = function() {
+ jQuery.fn.offset = function( options ) {
var elem = this[0];
if ( !elem || !elem.ownerDocument ) { return null; }
+ if ( options ) {
+ return this.each(function() {
+ jQuery.offset.setOffset( this, options );
+ });
+ }
if ( elem === elem.ownerDocument.body ) {
return jQuery.offset.bodyOffset( elem );
}
@@ -25,18 +35,18 @@ if ( "getBoundingClientRect" in document.documentElement ) {
var offsetParent = elem.offsetParent, prevOffsetParent = elem,
doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
body = doc.body, defaultView = doc.defaultView,
- prevComputedStyle = defaultView.getComputedStyle(elem, null),
+ prevComputedStyle = defaultView.getComputedStyle( elem, null ),
top = elem.offsetTop, left = elem.offsetLeft;
while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) { break; }
computedStyle = defaultView.getComputedStyle(elem, null);
- top -= elem.scrollTop;
+ top -= elem.scrollTop;
left -= elem.scrollLeft;
if ( elem === offsetParent ) {
- top += elem.offsetTop;
+ top += elem.offsetTop;
left += elem.offsetLeft;
if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
@@ -100,7 +110,7 @@ jQuery.offset = {
jQuery.offset.initialize = function(){};
},
- bodyOffset: function(body) {
+ bodyOffset: function( body ) {
var top = body.offsetTop, left = body.offsetLeft;
jQuery.offset.initialize();
@@ -111,6 +121,27 @@ jQuery.offset = {
}
return { top: top, left: left };
+ },
+
+ setOffset: function( elem, options ) {
+ // set position first, in-case top/left are set even on static elem
+ if ( /static/.test( jQuery.curCSS( elem, 'position' ) ) ) {
+ elem.style.position = 'relative';
+ }
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curTop = parseInt( jQuery.curCSS( elem, 'top', true ), 10 ) || 0,
+ curLeft = parseInt( jQuery.curCSS( elem, 'left', true ), 10) || 0,
+ props = {
+ top: (options.top - curOffset.top) + curTop,
+ left: (options.left - curOffset.left) + curLeft
+ };
+
+ if ( 'using' in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
}
};
2  test/data/offset/relative.html
View
@@ -6,7 +6,7 @@
<title>relative</title>
<style type="text/css" media="screen">
body { margin: 1px; padding: 5px; }
- div.relative { position: relative; margin: 1px; border: 2px solid #000; padding: 5px; width: 100px; height: 100px; background: #fff; overflow: hidden; }
+ div.relative { position: relative; top: 0; left: 0; margin: 1px; border: 2px solid #000; padding: 5px; width: 100px; height: 100px; background: #fff; overflow: hidden; }
#relative-2 { top: 20px; left: 20px; }
#marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; }
</style>
2  test/data/offset/static.html
View
@@ -6,7 +6,7 @@
<title>static</title>
<style type="text/css" media="screen">
body { margin: 1px; padding: 5px; }
- div.static { position: static; margin: 1px; border: 2px solid #000; padding: 5px; width: 100px; height: 100px; background: #fff; overflow: hidden; }
+ div.static { position: static; top: 0; left: 0; margin: 1px; border: 2px solid #000; padding: 5px; width: 100px; height: 100px; background: #fff; overflow: hidden; }
#static-2 { top: 20px; left: 20px; }
#marker { position: absolute; border: 2px solid #000; width: 50px; height: 50px; background: #ccc; }
</style>
284 test/unit/offset.js
View
@@ -1,107 +1,241 @@
module("offset");
testoffset("absolute", function( jQuery ) {
- equals( jQuery('#absolute-1').offset().top, 1, "jQuery('#absolute-1').offset().top" );
- equals( jQuery('#absolute-1').offset().left, 1, "jQuery('#absolute-1').offset().left" );
-
- equals( jQuery('#absolute-1-1').offset().top, 5, "jQuery('#absolute-1-1').offset().top" );
- equals( jQuery('#absolute-1-1').offset().left, 5, "jQuery('#absolute-1-1').offset().left" );
-
- equals( jQuery('#absolute-1-1-1').offset().top, 9, "jQuery('#absolute-1-1-1').offset().top" );
- equals( jQuery('#absolute-1-1-1').offset().left, 9, "jQuery('#absolute-1-1-1').offset().left" );
-
- equals( jQuery('#absolute-2').offset().top, 20, "jQuery('#absolute-2').offset().top" );
- equals( jQuery('#absolute-2').offset().left, 20, "jQuery('#absolute-2').offset().left" );
-
+ // get offset tests
+ var tests = [
+ { id: '#absolute-1', top: 1, left: 1 },
+ { id: '#absolute-1-1', top: 5, left: 5 },
+ { id: '#absolute-1-1-1', top: 9, left: 9 },
+ { id: '#absolute-2', top: 20, left: 20 }
+ ];
+ jQuery.each( tests, function() {
+ equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
+ equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
+ });
- equals( jQuery('#absolute-1').position().top, 0, "jQuery('#absolute-1').position().top" );
- equals( jQuery('#absolute-1').position().left, 0, "jQuery('#absolute-1').position().left" );
- equals( jQuery('#absolute-1-1').position().top, 1, "jQuery('#absolute-1-1').position().top" );
- equals( jQuery('#absolute-1-1').position().left, 1, "jQuery('#absolute-1-1').position().left" );
+ // get position
+ tests = [
+ { id: '#absolute-1', top: 0, left: 0 },
+ { id: '#absolute-1-1', top: 1, left: 1 },
+ { id: '#absolute-1-1-1', top: 1, left: 1 },
+ { id: '#absolute-2', top: 19, left: 19 }
+ ];
+ jQuery.each( tests, function() {
+ equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.id + "').position().top" );
+ equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
+ });
- equals( jQuery('#absolute-1-1-1').position().top, 1, "jQuery('#absolute-1-1-1').position().top" );
- equals( jQuery('#absolute-1-1-1').position().left, 1, "jQuery('#absolute-1-1-1').position().left" );
- equals( jQuery('#absolute-2').position().top, 19, "jQuery('#absolute-2').position().top" );
- equals( jQuery('#absolute-2').position().left, 19, "jQuery('#absolute-2').position().left" );
+ // set offset
+ tests = [
+ { id: '#absolute-2', top: 30, left: 30 },
+ { id: '#absolute-2', top: 10, left: 10 },
+ { id: '#absolute-2', top: -1, left: -1 },
+ { id: '#absolute-2', top: 19, left: 19 },
+ { id: '#absolute-1-1-1', top: 15, left: 15 },
+ { id: '#absolute-1-1-1', top: 5, left: 5 },
+ { id: '#absolute-1-1-1', top: -1, left: -1 },
+ { id: '#absolute-1-1-1', top: 9, left: 9 },
+ { id: '#absolute-1-1', top: 10, left: 10 },
+ { id: '#absolute-1-1', top: 0, left: 0 },
+ { id: '#absolute-1-1', top: -1, left: -1 },
+ { id: '#absolute-1-1', top: 5, left: 5 },
+ { id: '#absolute-1', top: 2, left: 2 },
+ { id: '#absolute-1', top: 0, left: 0 },
+ { id: '#absolute-1', top: -1, left: -1 },
+ { id: '#absolute-1', top: 1, left: 1 }
+ ];
+ jQuery.each( tests, function() {
+ jQuery( this.id ).offset({ top: this.top, left: this.left });
+ equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
+ equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
+
+ jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
+ jQuery( this ).css({
+ top: props.top + 1,
+ left: props.left + 1
+ });
+ }});
+ equals( jQuery( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + (this.top + 1) + ", using: fn })" );
+ equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
+ });
});
testoffset("relative", function( jQuery ) {
- var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8;
-
// IE is collapsing the top margin of 1px
- equals( jQuery('#relative-1').offset().top, ie ? 6 : 7, "jQuery('#relative-1').offset().top" );
- equals( jQuery('#relative-1').offset().left, 7, "jQuery('#relative-1').offset().left" );
-
- // IE is collapsing the top margin of 1px
- equals( jQuery('#relative-1-1').offset().top, ie ? 13 : 15, "jQuery('#relative-1-1').offset().top" );
- equals( jQuery('#relative-1-1').offset().left, 15, "jQuery('#relative-1-1').offset().left" );
+ var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8;
- // IE is collapsing the top margin of 1px
- equals( jQuery('#relative-2').offset().top, ie ? 141 : 142, "jQuery('#relative-2').offset().top" );
- equals( jQuery('#relative-2').offset().left, 27, "jQuery('#relative-2').offset().left" );
+ // get offset
+ var tests = [
+ { id: '#relative-1', top: ie ? 6 : 7, left: 7 },
+ { id: '#relative-1-1', top: ie ? 13 : 15, left: 15 },
+ { id: '#relative-2', top: ie ? 141 : 142, left: 27 }
+ ];
+ jQuery.each( tests, function() {
+ equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
+ equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
+ });
- // IE is collapsing the top margin of 1px
- equals( jQuery('#relative-1').position().top, ie ? 5 : 6, "jQuery('#relative-1').position().top" );
- equals( jQuery('#relative-1').position().left, 6, "jQuery('#relative-1').position().left" );
+ // get position
+ tests = [
+ { id: '#relative-1', top: ie ? 5 : 6, left: 6 },
+ { id: '#relative-1-1', top: ie ? 4 : 5, left: 5 },
+ { id: '#relative-2', top: ie ? 140 : 141, left: 26 }
+ ];
+ jQuery.each( tests, function() {
+ equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.id + "').position().top" );
+ equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
+ });
- // IE is collapsing the top margin of 1px
- equals( jQuery('#relative-1-1').position().top, ie ? 4 : 5, "jQuery('#relative-1-1').position().top" );
- equals( jQuery('#relative-1-1').position().left, 5, "jQuery('#relative-1-1').position().left" );
- // IE is collapsing the top margin of 1px
- equals( jQuery('#relative-2').position().top, ie ? 140 : 141, "jQuery('#relative-2').position().top" );
- equals( jQuery('#relative-2').position().left, 26, "jQuery('#relative-2').position().left" );
+ // set offset
+ tests = [
+ { id: '#relative-2', top: 200, left: 50 },
+ { id: '#relative-2', top: 100, left: 10 },
+ { id: '#relative-2', top: -5, left: -5 },
+ { id: '#relative-2', top: 142, left: 27 },
+ { id: '#relative-1-1', top: 100, left: 100 },
+ { id: '#relative-1-1', top: 5, left: 5 },
+ { id: '#relative-1-1', top: -1, left: -1 },
+ { id: '#relative-1-1', top: 15, left: 15 },
+ { id: '#relative-1', top: 100, left: 100 },
+ { id: '#relative-1', top: 0, left: 0 },
+ { id: '#relative-1', top: -1, left: -1 },
+ { id: '#relative-1', top: 7, left: 7 }
+ ];
+ jQuery.each( tests, function() {
+ jQuery( this.id ).offset({ top: this.top, left: this.left });
+ equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
+ equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
+
+ jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
+ jQuery( this ).css({
+ top: props.top + 1,
+ left: props.left + 1
+ });
+ }});
+ equals( jQuery( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + (this.top + 1) + ", using: fn })" );
+ equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
+ });
});
testoffset("static", function( jQuery ) {
- var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8;
-
- // IE is collapsing the top margin of 1px
- equals( jQuery('#static-1').offset().top, ie ? 6 : 7, "jQuery('#static-1').offset().top" );
- equals( jQuery('#static-1').offset().left, 7, "jQuery('#static-1').offset().left" );
-
- // IE is collapsing the top margin of 1px
- equals( jQuery('#static-1-1').offset().top, ie ? 13 : 15, "jQuery('#static-1-1').offset().top" );
- equals( jQuery('#static-1-1').offset().left, 15, "jQuery('#static-1-1').offset().left" );
-
// IE is collapsing the top margin of 1px
- equals( jQuery('#static-1-1-1').offset().top, ie ? 20 : 23, "jQuery('#static-1-1-1').offset().top" );
- equals( jQuery('#static-1-1-1').offset().left, 23, "jQuery('#static-1-1-1').offset().left" );
-
- // IE is collapsing the top margin of 1px
- equals( jQuery('#static-2').offset().top, ie ? 121 : 122, "jQuery('#static-2').offset().top" );
- equals( jQuery('#static-2').offset().left, 7, "jQuery('#static-2').offset().left" );
+ var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8;
+ // get offset
+ var tests = [
+ { id: '#static-1', top: ie ? 6 : 7, left: 7 },
+ { id: '#static-1-1', top: ie ? 13 : 15, left: 15 },
+ { id: '#static-1-1-1', top: ie ? 20 : 23, left: 23 },
+ { id: '#static-2', top: ie ? 121 : 122, left: 7 }
+ ];
+ jQuery.each( tests, function() {
+ equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
+ equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
+ });
- // IE is collapsing the top margin of 1px
- equals( jQuery('#static-1').position().top, ie ? 5 : 6, "jQuery('#static-1').position().top" );
- equals( jQuery('#static-1').position().left, 6, "jQuery('#static-1').position().left" );
- // IE is collapsing the top margin of 1px
- equals( jQuery('#static-1-1').position().top, ie ? 12 : 14, "jQuery('#static-1-1').position().top" );
- equals( jQuery('#static-1-1').position().left, 14, "jQuery('#static-1-1').position().left" );
+ // get position
+ tests = [
+ { id: '#static-1', top: ie ? 5 : 6, left: 6 },
+ { id: '#static-1-1', top: ie ? 12 : 14, left: 14 },
+ { id: '#static-1-1-1', top: ie ? 19 : 22, left: 22 },
+ { id: '#static-2', top: ie ? 120 : 121, left: 6 }
+ ];
+ jQuery.each( tests, function() {
+ equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.top + "').position().top" );
+ equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.left +"').position().left" );
+ });
- // IE is collapsing the top margin of 1px
- equals( jQuery('#static-1-1-1').position().top, ie ? 19 : 22, "jQuery('#static-1-1-1').position().top" );
- equals( jQuery('#static-1-1-1').position().left, 22, "jQuery('#static-1-1-1').position().left" );
- // IE is collapsing the top margin of 1px
- equals( jQuery('#static-2').position().top, ie ? 120 : 121, "jQuery('#static-2').position().top" );
- equals( jQuery('#static-2').position().left, 6, "jQuery('#static-2').position().left" );
+ // set offset
+ tests = [
+ { id: '#static-2', top: 200, left: 200 },
+ { id: '#static-2', top: 100, left: 100 },
+ { id: '#static-2', top: -2, left: -2 },
+ { id: '#static-2', top: 121, left: 6 },
+ { id: '#static-1-1-1', top: 50, left: 50 },
+ { id: '#static-1-1-1', top: 10, left: 10 },
+ { id: '#static-1-1-1', top: -1, left: -1 },
+ { id: '#static-1-1-1', top: 22, left: 22 },
+ { id: '#static-1-1', top: 25, left: 25 },
+ { id: '#static-1-1', top: 10, left: 10 },
+ { id: '#static-1-1', top: -3, left: -3 },
+ { id: '#static-1-1', top: 14, left: 14 },
+ { id: '#static-1', top: 30, left: 30 },
+ { id: '#static-1', top: 2, left: 2 },
+ { id: '#static-1', top: -2, left: -2 },
+ { id: '#static-1', top: 7, left: 7 }
+ ];
+ jQuery.each( tests, function() {
+ jQuery( this.id ).offset({ top: this.top, left: this.left });
+ equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
+ equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
+
+ jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
+ jQuery( this ).css({
+ top: props.top + 1,
+ left: props.left + 1
+ });
+ }});
+ equals( jQuery( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + (this.top + 1) + ", using: fn })" );
+ equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
+ });
});
-if ( jQuery.offset.supportsFixedPosition ) {
- testoffset("fixed", function( jQuery ) {
- equals( jQuery('#fixed-1').offset().top, 1001, "jQuery('#fixed-1').offset().top" );
- equals( jQuery('#fixed-1').offset().left, 1001, "jQuery('#fixed-1').offset().left" );
+testoffset("fixed", function( jQuery ) {
+ jQuery.offset.initialize();
+
+ var tests = [
+ { id: '#fixed-1', top: 1001, left: 1001 },
+ { id: '#fixed-2', top: 1021, left: 1021 }
+ ];
+ jQuery.each( tests, function() {
+ if ( jQuery.offset.supportsFixedPosition ) {
+ equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
+ equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
+ } else {
+ // need to have same number of assertions
+ ok( true, 'Fixed position is not supported' );
+ ok( true, 'Fixed position is not supported' );
+ }
+ });
- equals( jQuery('#fixed-2').offset().top, 1021, "jQuery('#fixed-2').offset().top" );
- equals( jQuery('#fixed-2').offset().left, 1021, "jQuery('#fixed-2').offset().left" );
+ tests = [
+ { id: '#fixed-1', top: 100, left: 100 },
+ { id: '#fixed-1', top: 0, left: 0 },
+ { id: '#fixed-1', top: -4, left: -4 },
+ { id: '#fixed-2', top: 200, left: 200 },
+ { id: '#fixed-2', top: 0, left: 0 },
+ { id: '#fixed-2', top: -5, left: -5 }
+ ];
+
+ jQuery.each( tests, function() {
+ if ( jQuery.offset.supportsFixedPosition ) {
+ jQuery( this.id ).offset({ top: this.top, left: this.left });
+ equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
+ equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
+
+ jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
+ jQuery( this ).css({
+ top: props.top + 1,
+ left: props.left + 1
+ });
+ }});
+ equals( jQuery( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + (this.top + 1) + ", using: fn })" );
+ equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
+ } else {
+ // need to have same number of assertions
+ ok( true, 'Fixed position is not supported' );
+ ok( true, 'Fixed position is not supported' );
+ ok( true, 'Fixed position is not supported' );
+ ok( true, 'Fixed position is not supported' );
+ }
});
-}
+});
testoffset("table", function( jQuery ) {
var ie = jQuery.browser.msie;
Please sign in to comment.
Something went wrong with that request. Please try again.