3 testoffset("absolute"/* in iframe */, function($, iframe) {
6 var doc = iframe.document, tests;
8 // force a scroll value on the main window
9 // this insures that the results will be wrong
10 // if the offset method is using the scroll offset
11 // of the parent window
12 var forceScroll = jQuery('<div>', { width: 2000, height: 2000 }).appendTo('body');
13 window.scrollTo(1, 1);
17 { id: '#absolute-1', top: 1, left: 1 }
19 jQuery.each( tests, function() {
20 equals( jQuery( this.id, doc ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
21 equals( jQuery( this.id, doc ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
27 { id: '#absolute-1', top: 0, left: 0 }
29 jQuery.each( tests, function() {
30 equals( jQuery( this.id, doc ).position().top, this.top, "jQuery('" + this.id + "').position().top" );
31 equals( jQuery( this.id, doc ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
37 testoffset("absolute", function( jQuery ) {
42 { id: '#absolute-1', top: 1, left: 1 },
43 { id: '#absolute-1-1', top: 5, left: 5 },
44 { id: '#absolute-1-1-1', top: 9, left: 9 },
45 { id: '#absolute-2', top: 20, left: 20 }
47 jQuery.each( tests, function() {
48 equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
49 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
55 { id: '#absolute-1', top: 0, left: 0 },
56 { id: '#absolute-1-1', top: 1, left: 1 },
57 { id: '#absolute-1-1-1', top: 1, left: 1 },
58 { id: '#absolute-2', top: 19, left: 19 }
60 jQuery.each( tests, function() {
61 equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.id + "').position().top" );
62 equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
68 { id: '#absolute-2', top: 30, left: 30 },
69 { id: '#absolute-2', top: 10, left: 10 },
70 { id: '#absolute-2', top: -1, left: -1 },
71 { id: '#absolute-2', top: 19, left: 19 },
72 { id: '#absolute-1-1-1', top: 15, left: 15 },
73 { id: '#absolute-1-1-1', top: 5, left: 5 },
74 { id: '#absolute-1-1-1', top: -1, left: -1 },
75 { id: '#absolute-1-1-1', top: 9, left: 9 },
76 { id: '#absolute-1-1', top: 10, left: 10 },
77 { id: '#absolute-1-1', top: 0, left: 0 },
78 { id: '#absolute-1-1', top: -1, left: -1 },
79 { id: '#absolute-1-1', top: 5, left: 5 },
80 { id: '#absolute-1', top: 2, left: 2 },
81 { id: '#absolute-1', top: 0, left: 0 },
82 { id: '#absolute-1', top: -1, left: -1 },
83 { id: '#absolute-1', top: 1, left: 1 }
85 jQuery.each( tests, function() {
86 jQuery( this.id ).offset({ top: this.top, left: this.left });
87 equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
88 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
90 var top = this.top, left = this.left;
92 jQuery( this.id ).offset(function(i, val){
93 equals( val.top, top, "Verify incoming top position." );
94 equals( val.left, left, "Verify incoming top position." );
95 return { top: top + 1, left: left + 1 };
97 equals( jQuery( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
98 equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
100 jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
106 equals( jQuery( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + (this.top + 1) + ", using: fn })" );
107 equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
111 testoffset("relative", function( jQuery ) {
114 // IE is collapsing the top margin of 1px
115 var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8;
119 { id: '#relative-1', top: ie ? 6 : 7, left: 7 },
120 { id: '#relative-1-1', top: ie ? 13 : 15, left: 15 },
121 { id: '#relative-2', top: ie ? 141 : 142, left: 27 }
123 jQuery.each( tests, function() {
124 equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
125 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
131 { id: '#relative-1', top: ie ? 5 : 6, left: 6 },
132 { id: '#relative-1-1', top: ie ? 4 : 5, left: 5 },
133 { id: '#relative-2', top: ie ? 140 : 141, left: 26 }
135 jQuery.each( tests, function() {
136 equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.id + "').position().top" );
137 equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.id + "').position().left" );
143 { id: '#relative-2', top: 200, left: 50 },
144 { id: '#relative-2', top: 100, left: 10 },
145 { id: '#relative-2', top: -5, left: -5 },
146 { id: '#relative-2', top: 142, left: 27 },
147 { id: '#relative-1-1', top: 100, left: 100 },
148 { id: '#relative-1-1', top: 5, left: 5 },
149 { id: '#relative-1-1', top: -1, left: -1 },
150 { id: '#relative-1-1', top: 15, left: 15 },
151 { id: '#relative-1', top: 100, left: 100 },
152 { id: '#relative-1', top: 0, left: 0 },
153 { id: '#relative-1', top: -1, left: -1 },
154 { id: '#relative-1', top: 7, left: 7 }
156 jQuery.each( tests, function() {
157 jQuery( this.id ).offset({ top: this.top, left: this.left });
158 equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
159 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
161 jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
167 equals( jQuery( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + (this.top + 1) + ", using: fn })" );
168 equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
172 testoffset("static", function( jQuery ) {
175 // IE is collapsing the top margin of 1px
176 var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8;
180 { id: '#static-1', top: ie ? 6 : 7, left: 7 },
181 { id: '#static-1-1', top: ie ? 13 : 15, left: 15 },
182 { id: '#static-1-1-1', top: ie ? 20 : 23, left: 23 },
183 { id: '#static-2', top: ie ? 121 : 122, left: 7 }
185 jQuery.each( tests, function() {
186 equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
187 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
193 { id: '#static-1', top: ie ? 5 : 6, left: 6 },
194 { id: '#static-1-1', top: ie ? 12 : 14, left: 14 },
195 { id: '#static-1-1-1', top: ie ? 19 : 22, left: 22 },
196 { id: '#static-2', top: ie ? 120 : 121, left: 6 }
198 jQuery.each( tests, function() {
199 equals( jQuery( this.id ).position().top, this.top, "jQuery('" + this.top + "').position().top" );
200 equals( jQuery( this.id ).position().left, this.left, "jQuery('" + this.left +"').position().left" );
206 { id: '#static-2', top: 200, left: 200 },
207 { id: '#static-2', top: 100, left: 100 },
208 { id: '#static-2', top: -2, left: -2 },
209 { id: '#static-2', top: 121, left: 6 },
210 { id: '#static-1-1-1', top: 50, left: 50 },
211 { id: '#static-1-1-1', top: 10, left: 10 },
212 { id: '#static-1-1-1', top: -1, left: -1 },
213 { id: '#static-1-1-1', top: 22, left: 22 },
214 { id: '#static-1-1', top: 25, left: 25 },
215 { id: '#static-1-1', top: 10, left: 10 },
216 { id: '#static-1-1', top: -3, left: -3 },
217 { id: '#static-1-1', top: 14, left: 14 },
218 { id: '#static-1', top: 30, left: 30 },
219 { id: '#static-1', top: 2, left: 2 },
220 { id: '#static-1', top: -2, left: -2 },
221 { id: '#static-1', top: 7, left: 7 }
223 jQuery.each( tests, function() {
224 jQuery( this.id ).offset({ top: this.top, left: this.left });
225 equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
226 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
228 jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
234 equals( jQuery( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + (this.top + 1) + ", using: fn })" );
235 equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
239 testoffset("fixed", function( jQuery ) {
242 jQuery.offset.initialize();
245 { id: '#fixed-1', top: 1001, left: 1001 },
246 { id: '#fixed-2', top: 1021, left: 1021 }
248 jQuery.each( tests, function() {
249 if ( jQuery.offset.supportsFixedPosition ) {
250 equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset().top" );
251 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset().left" );
253 // need to have same number of assertions
254 ok( true, 'Fixed position is not supported' );
255 ok( true, 'Fixed position is not supported' );
260 { id: '#fixed-1', top: 100, left: 100 },
261 { id: '#fixed-1', top: 0, left: 0 },
262 { id: '#fixed-1', top: -4, left: -4 },
263 { id: '#fixed-2', top: 200, left: 200 },
264 { id: '#fixed-2', top: 0, left: 0 },
265 { id: '#fixed-2', top: -5, left: -5 }
268 jQuery.each( tests, function() {
269 if ( jQuery.offset.supportsFixedPosition ) {
270 jQuery( this.id ).offset({ top: this.top, left: this.left });
271 equals( jQuery( this.id ).offset().top, this.top, "jQuery('" + this.id + "').offset({ top: " + this.top + " })" );
272 equals( jQuery( this.id ).offset().left, this.left, "jQuery('" + this.id + "').offset({ left: " + this.left + " })" );
274 jQuery( this.id ).offset({ top: this.top, left: this.left, using: function( props ) {
280 equals( jQuery( this.id ).offset().top, this.top + 1, "jQuery('" + this.id + "').offset({ top: " + (this.top + 1) + ", using: fn })" );
281 equals( jQuery( this.id ).offset().left, this.left + 1, "jQuery('" + this.id + "').offset({ left: " + (this.left + 1) + ", using: fn })" );
283 // need to have same number of assertions
284 ok( true, 'Fixed position is not supported' );
285 ok( true, 'Fixed position is not supported' );
286 ok( true, 'Fixed position is not supported' );
287 ok( true, 'Fixed position is not supported' );
292 testoffset("table", function( jQuery ) {
295 equals( jQuery('#table-1').offset().top, 6, "jQuery('#table-1').offset().top" );
296 equals( jQuery('#table-1').offset().left, 6, "jQuery('#table-1').offset().left" );
298 equals( jQuery('#th-1').offset().top, 10, "jQuery('#th-1').offset().top" );
299 equals( jQuery('#th-1').offset().left, 10, "jQuery('#th-1').offset().left" );
302 testoffset("scroll", function( jQuery, win ) {
305 var ie = jQuery.browser.msie && parseInt( jQuery.browser.version ) < 8;
307 // IE is collapsing the top margin of 1px
308 equals( jQuery('#scroll-1').offset().top, ie ? 6 : 7, "jQuery('#scroll-1').offset().top" );
309 equals( jQuery('#scroll-1').offset().left, 7, "jQuery('#scroll-1').offset().left" );
311 // IE is collapsing the top margin of 1px
312 equals( jQuery('#scroll-1-1').offset().top, ie ? 9 : 11, "jQuery('#scroll-1-1').offset().top" );
313 equals( jQuery('#scroll-1-1').offset().left, 11, "jQuery('#scroll-1-1').offset().left" );
316 // scroll offset tests .scrollTop/Left
317 equals( jQuery('#scroll-1').scrollTop(), 5, "jQuery('#scroll-1').scrollTop()" );
318 equals( jQuery('#scroll-1').scrollLeft(), 5, "jQuery('#scroll-1').scrollLeft()" );
320 equals( jQuery('#scroll-1-1').scrollTop(), 0, "jQuery('#scroll-1-1').scrollTop()" );
321 equals( jQuery('#scroll-1-1').scrollLeft(), 0, "jQuery('#scroll-1-1').scrollLeft()" );
323 // equals( jQuery('body').scrollTop(), 0, "jQuery('body').scrollTop()" );
324 // equals( jQuery('body').scrollLeft(), 0, "jQuery('body').scrollTop()" );
328 equals( jQuery(win).scrollTop(), 1000, "jQuery(window).scrollTop()" );
329 equals( jQuery(win).scrollLeft(), 1000, "jQuery(window).scrollLeft()" );
331 equals( jQuery(win.document).scrollTop(), 1000, "jQuery(document).scrollTop()" );
332 equals( jQuery(win.document).scrollLeft(), 1000, "jQuery(document).scrollLeft()" );
334 // test jQuery using parent window/document
335 // jQuery reference here is in the iframe
336 window.scrollTo(0,0);
337 equals( jQuery(window).scrollTop(), 0, "jQuery(window).scrollTop() other window" );
338 equals( jQuery(window).scrollLeft(), 0, "jQuery(window).scrollLeft() other window" );
339 equals( jQuery(document).scrollTop(), 0, "jQuery(window).scrollTop() other document" );
340 equals( jQuery(document).scrollLeft(), 0, "jQuery(window).scrollLeft() other document" );
343 testoffset("body", function( jQuery ) {
346 equals( jQuery('body').offset().top, 1, "jQuery('#body').offset().top" );
347 equals( jQuery('body').offset().left, 1, "jQuery('#body').offset().left" );
350 test("Chaining offset(coords) returns jQuery object", function() {
352 var coords = { top: 1, left: 1 };
353 equals( jQuery("#absolute-1").offset(coords).selector, "#absolute-1", "offset(coords) returns jQuery object" );
354 equals( jQuery("#non-existent").offset(coords).selector, "#non-existent", "offset(coords) with empty jQuery set returns jQuery object" );
357 test("offsetParent", function(){
360 var body = jQuery("body").offsetParent();
361 equals( body.length, 1, "Only one offsetParent found." );
362 equals( body[0], document.body, "The body is its own offsetParent." );
364 var header = jQuery("#qunit-header").offsetParent();
365 equals( header.length, 1, "Only one offsetParent found." );
366 equals( header[0], document.body, "The body is the offsetParent." );
368 var div = jQuery("#nothiddendivchild").offsetParent();
369 equals( div.length, 1, "Only one offsetParent found." );
370 equals( div[0], document.body, "The body is the offsetParent." );
372 jQuery("#nothiddendiv").css("position", "relative");
374 div = jQuery("#nothiddendivchild").offsetParent();
375 equals( div.length, 1, "Only one offsetParent found." );
376 equals( div[0], jQuery("#nothiddendiv")[0], "The div is the offsetParent." );
378 div = jQuery("body, #nothiddendivchild").offsetParent();
379 equals( div.length, 2, "Two offsetParent found." );
380 equals( div[0], document.body, "The body is the offsetParent." );
381 equals( div[1], jQuery("#nothiddendiv")[0], "The div is the offsetParent." );
384 function testoffset(name, fn) {
386 test(name, function() {
387 // pause execution for now
390 // load fixture in iframe
391 var iframe = loadFixture(),
392 win = iframe.contentWindow,
393 interval = setInterval( function() {
394 if ( win && win.jQuery && win.jQuery.isReady ) {
395 clearInterval( interval );
398 // call actual tests passing the correct jQuery isntance to use
399 fn.call( this, win.jQuery, win );
400 document.body.removeChild( iframe );
406 function loadFixture() {
407 var src = './data/offset/' + name + '.html?' + parseInt( Math.random()*1000 ),
408 iframe = jQuery('<iframe />').css({
409 width: 500, height: 500, position: 'absolute', top: -600, left: -600, visiblity: 'hidden'
410 }).appendTo('body')[0];
411 iframe.contentWindow.location = src;