Why doesnt jQuery offset() work with table based layout in IE?
I have some quirky problems with IE7+ (yes big surprise) when trying to find the position of an element in order to render a translucent div on top of that element.
jQuery's offset() and position() functions work in the documented and expected ways when using DIVs or other layout markup. The problem arises when using table based layout.
Example:
<html>
<body style="margin: 0px;">
<input type="button" onclick="addlayer('tobeOverlayed')" value="Add Layer" />
<div style='position: absolute; left: 40px; top: 30px;'>
<table cellpadding="0" cellspacing="0" style="position: relative; top:15px;">
<tr>
<td style="width: 开发者_如何学编程100px;' />
<td style="width: 400px;'>
<table cellpadding="0" cellspacing="0" >
<tr style='height: 70px;">
<td style='width: 5px;'></td>
<td></td>
</tr>
<tr style='height: 70px;">
<td style='width: 5px;'></td>
<td>
<div id="tobeOverlayed" style="background: Red;">Render a translucent layer over me</div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</body>
</html>
When I try to position a layer on top of the div with id=tobeOverlayed --- neither offset or position are giving me the correct top/left values.
The layer that I am positioning has to end up as a sibling of the element it is overlayed on top of (if the element's container is scrolled, I want my overlay to be scrolled with it).
Example markup after adding my overlay:
<html>
<body style="margin: 0px;">
<input type="button" onclick="addlayer('tobeOverlayed')" value="Add Layer" />
<div style='position: absolute; left: 40px; top: 30px;'>
<table cellpadding="0" cellspacing="0" style="position: relative; top:15px;">
<tr>
<td style="width: 100px;' />
<td style="width: 400px;'>
<table cellpadding="0" cellspacing="0" >
<tr style='height: 70px;">
<td style='width: 5px;'></td>
<td></td>
</tr>
<tr style='height: 70px;">
<td style='width: 5px;'></td>
<td>
<div id="tobeOverlayed" style="background: Red;">Render a translucent layer over me</div>
<div class="Overlay" style="position: absolute; top: 0px; left; 40px" />
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</body>
</html>
The top/left settings are an example - don't take it literally.
In this example calling:
var offsetPos = $("#tobeOverlayed").offset();
gives me coordinates of left,top = ( 40, 122 )
var pos = $("#tobeOverlayed").position();
gives me coordinates of left,top = ( 0, 7 )
Neither of these is the right top,left values to use for my overlay --- which isn't completely unexpected... offset() gives you the coordinates relative to the document - which sense I'm inserting my element as a sibling wouldn't be the right to use.
However position() - should give the right coordinates to use, shouldn't it? 0,7 does not position the overlay correctly - maybe this is an IE bug due to the container being a table cell --- but the overlay gets positioned relative to the table element - not the table cell.
Is this a known quirk of IE? Or is my understanding wrong of position and offset?
Ok, after much gnashing of teeth - the simple answer is - for jQuery's position function to work - the parent container MUST be positioned with position: absolute or position: relative.
I didnt see that in the jQuery documentation - but found reference to it in the following question: CSS absolute positioning elements inside a div
Once the parent container was set to position: relative
$(element).position()
worked perfectly.
精彩评论