Forum Moderators: open

Message Too Old, No Replies

Finding the position of an element

Differences in Safari (and IE depending on DOCTYPE)

         

CgiBin

4:20 pm on May 9, 2005 (gmt 0)

10+ Year Member



Hello,
I'm trying to find the absolute position within a document of an arbitrary element. The element isn't absolutely positioned, so I cant simply read the style.top, etc.

I've found a couple examples of the JS code to do this, and it works fine:

function findX(obj) {
var x = 0;
while (obj.offsetParent) {
x += obj.offsetLeft
obj = obj.offsetParent;
}

alert(x);
}

The problem is that Safari (1.3) doesn't include the document body's margins. It does however include any margins of the element itself, or any other containing elements' margins.

Also, IE if you use a doctype AND supply a URL in the doctype has the exact same behavior.

Firefox and IE without a URL in the doctype work correctly.

Heres a complete example:

<html>
<head>
<style>
* {
font-family: Arial, Verdana, Helvetica, sans-serif;
font-size: 12px;
margin: 0px;
padding: 0px;
}

body {
margin: 25px;
}
</style>
<script>
function findX(obj) {
var x = 0;
while (obj.offsetParent) {
x += obj.offsetLeft
obj = obj.offsetParent;
}

alert(x);
}
</script>
</head>
<body>
<p><a href="#" onclick="findX(this)">test</a></p>
<div style="height: 20px"></div>
<table>
<tr><td>
<a href="#" onclick="findX(this)">test</a>
</td><td>
<a href="#" onclick="findX(this)">test</a>
</td><td>
<a href="#" onclick="findX(this)">test</a>
</td></tr>
</table>
<div style="height: 20px"></div>
<div style="margin: 10px">
<p><a href="#" onclick="findX(this)">test</a></p>
<div>
</body>
</html>

I'm stuck at how to adjust the findX function to give a consistent value for all 3 browsers.

CgiBin

6:46 pm on May 9, 2005 (gmt 0)

10+ Year Member



Sorry, originally posted in HTML/Browsers section since it seemed more like a browser difference rather than a pure JavaScript problem... just happen to be using JavaScript to demonstrate the problem.

Anyway, I think I have found a possible solution... I created a function:

function docInfo() {
var foo = false;

if (document.compatMode) {
if ( document.compatMode!= "BackCompat" &&!document.doctype ) {
if (document.getElementsByTagName('!')[0].text.indexOf("dtd")!= -1)
foo = true;
}
} else {
foo = true;
}

return foo;
}

Then adjust the findX as follows:

function findX(obj) {
var x = 0;
while (obj.offsetParent) {
x += obj.offsetLeft
obj = obj.offsetParent;
if ( obj && (obj.tagName == "BODY") && docInfo() )
x+= obj.offsetLeft;
}

return x;
}

Anyone see any problems? I think I could probably move the extra if that I added to findX outside the while loop, but it seems to work fine as is.

CgiBin

6:54 pm on May 9, 2005 (gmt 0)

10+ Year Member



Oh my God!
I feel like such a PUTZ!

function findX(obj) {
var x = 0;
while (obj) {
x += obj.offsetLeft
obj = obj.offsetParent;
}
alert(x);
}

just remove the .offsetParent from the while clause!

Sheesh... it hit me about 2 minutes after posting my 1st fix.