|
| 1 | +jQuery.fn.offset = function() { |
| 2 | + var left = 0, top = 0, elem = this[0], results; |
| 3 | + |
| 4 | + if ( elem ) with ( jQuery.browser ) { |
| 5 | + var absolute = jQuery.css(elem, "position") == "absolute", |
| 6 | + parent = elem.parentNode, |
| 7 | + offsetParent = elem.offsetParent, |
| 8 | + doc = elem.ownerDocument, |
| 9 | + safari2 = safari && !absolute && parseInt(version) < 522; |
| 10 | + |
| 11 | + // Use getBoundingClientRect if available |
| 12 | + if ( elem.getBoundingClientRect ) { |
| 13 | + box = elem.getBoundingClientRect(); |
| 14 | + |
| 15 | + // Add the document scroll offsets |
| 16 | + add( |
| 17 | + box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft), |
| 18 | + box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop) |
| 19 | + ); |
| 20 | + |
| 21 | + // IE adds the HTML element's border, by default it is medium which is 2px |
| 22 | + // IE 6 and IE 7 quirks mode the border width is overwritable by the following css html { border: 0; } |
| 23 | + // IE 7 standards mode, the border is always 2px |
| 24 | + if ( msie ) { |
| 25 | + var border = jQuery("html").css("borderWidth"); |
| 26 | + border = (border == "medium" || jQuery.boxModel && parseInt(version) >= 7) && 2 || border; |
| 27 | + add( -border, -border ); |
| 28 | + } |
| 29 | + |
| 30 | + // Otherwise loop through the offsetParents and parentNodes |
| 31 | + } else { |
| 32 | + |
| 33 | + // Initial element offsets |
| 34 | + add( elem.offsetLeft, elem.offsetTop ); |
| 35 | + |
| 36 | + // Get parent offsets |
| 37 | + while ( offsetParent ) { |
| 38 | + // Add offsetParent offsets |
| 39 | + add( offsetParent.offsetLeft, offsetParent.offsetTop ); |
| 40 | + |
| 41 | + // Mozilla and Safari > 2 does not include the border on offset parents |
| 42 | + // However Mozilla adds the border for table cells |
| 43 | + if ( mozilla && /^t[d|h]$/i.test(parent.tagName) || !safari2 ) |
| 44 | + border( offsetParent ); |
| 45 | + |
| 46 | + // Safari <= 2 doubles body offsets with an absolutely positioned element or parent |
| 47 | + if ( safari2 && !absolute && jQuery.css(offsetParent, "position") == "absolute" ) |
| 48 | + absolute = true; |
| 49 | + |
| 50 | + // Get next offsetParent |
| 51 | + offsetParent = offsetParent.offsetParent; |
| 52 | + } |
| 53 | + |
| 54 | + // Get parent scroll offsets |
| 55 | + while ( parent.tagName && /^body|html$/i.test(parent.tagName) ) { |
| 56 | + // Work around opera inline/table scrollLeft/Top bug |
| 57 | + if ( /^inline|table-row.*$/i.test(jQuery.css(parent, "display")) ) |
| 58 | + // Subtract parent scroll offsets |
| 59 | + add( -parent.scrollLeft, -parent.scrollTop ); |
| 60 | + |
| 61 | + // Mozilla does not add the border for a parent that has overflow != visible |
| 62 | + if ( mozilla && jQuery.css(parent, "overflow") != "visible" ) |
| 63 | + border( parent ); |
| 64 | + |
| 65 | + // Get next parent |
| 66 | + parent = parent.parentNode; |
| 67 | + } |
| 68 | + |
| 69 | + // Safari doubles body offsets with an absolutely positioned element or parent |
| 70 | + if ( safari && absolute ) |
| 71 | + add( -doc.body.offsetLeft, -doc.body.offsetTop ); |
| 72 | + } |
| 73 | + |
| 74 | + // Return an object with top and left properties |
| 75 | + results = { top: top, left: left }; |
| 76 | + } |
| 77 | + |
| 78 | + return results; |
| 79 | + |
| 80 | + function border(elem) { |
| 81 | + add( jQuery.css(elem, "borderLeftWidth"), jQuery.css(elem, "borderTopWidth") ); |
| 82 | + } |
| 83 | + |
| 84 | + function add(l, t) { |
| 85 | + left += parseInt(l) || 0; |
| 86 | + top += parseInt(t) || 0; |
| 87 | + } |
| 88 | +}; |
0 commit comments