How can one find the absolute x-value (from body 0) of the lower edge of a given element

D

Dag Sunde

Imagine a mess of div-elements nested inside each other
some relative, some absolute.

Some of them grows when their children grows...

And at some point, I want the x-coordinate of the bottom
edge of the element that is lowest down on the page.

Of course I need to support the most popular UAs on each
major platform (Not NS4.x)

(In my particular case, I'm only interested in div elements)...

Any hints on this?

TIA...
 
M

Matt Kruse

Dag said:
And at some point, I want the x-coordinate of the bottom
edge of the element that is lowest down on the page.

Finding the position of an object on a page with arbitrary layout can be
challenging.
My current stab at it can be found here:
http://www.mattkruse.com/javascript/objectposition.js

Although, it doesn't currently handle absolutely-positioned elements, and IE
has some problems with relative-positioned objects (still trying to debug
that one!)

If you send me a sample test case, I can use it to verify the functionality
of my lib as I go forward.
 
J

Jonas Raoni

Dag Sunde escreveu:
And at some point, I want the x-coordinate of the bottom
edge of the element that is lowest down on the page.

If you have no way to keep the lowest <div> safe, like "if(newDiv <
lowest) lowest = newDiv", then I can't see a nice way to do it (without
loop) :)

Try the code bellow, I didn't tested much... =/

function getLowestDown(tagName){
function getRect(o){
for(var r = {l: o.offsetLeft, t: o.offsetTop, w: o.offsetWidth, h:
o.offsetHeight};
o = o.offsetParent; r.l += o.offsetLeft, r.t += o.offsetTop);
return r;
}
var list = document.getElementsByTagName(tagName), i = list.length,
lowest = i ? {o: list[0], r: getRect(list[0])} : {o: null, r: {l: 0,
t: 0, w: 0, h: 0}};
for(var r = lowest.r, y = r.t + r.h; i; (r = getRect(list[--i])).t +
r.h > y && (lowest = {o: list, r: r}, y = r.t + r.h));
return lowest;
}

var x = getLowestDown("div");
alert([x.o, "left: " + x.r.l, "top: " + x.r.t, "width: " + x.r.w,
"height: " + x.r.h].join("\n"));
 
D

Dag Sunde

Matt Kruse said:
Finding the position of an object on a page with arbitrary layout can be
challenging.
My current stab at it can be found here:
http://www.mattkruse.com/javascript/objectposition.js

Thank you, I'll take a look at it...

Although, it doesn't currently handle absolutely-positioned elements, and
IE has some problems with relative-positioned objects (still trying to
debug that one!)

If you send me a sample test case, I can use it to verify the
functionality of my lib as I go forward.

Will do, as soon as I've made a self-contained sample...
(This is for a designer friend of mine, and she doesn't
own the pages)...

Her task is to add a footer to an exsisting design.
If the content of the page fits into the client-area,
the footer is supposed to lock itself to the bottom
of the window.
If the content exceeds the height of the window, the
footer should be absolutely positioned x pixels below
the lowest content.
 
D

Dag Sunde

Jonas Raoni said:
Dag Sunde escreveu:

If you have no way to keep the lowest <div> safe, like "if(newDiv <
lowest) lowest = newDiv", then I can't see a nice way to do it (without
loop) :)

Try the code bellow, I didn't tested much... =/
Thanks!

I'll give it a try...
 
D

Dag Sunde

Jonas Raoni said:
Dag Sunde escreveu:
And at some point, I want the x-coordinate of the bottom
edge of the element that is lowest down on the page.

If you have no way to keep the lowest <div> safe, like "if(newDiv <
lowest) lowest = newDiv", then I can't see a nice way to do it (without
loop) :)

Try the code bellow, I didn't tested much... =/

function getLowestDown(tagName){
function getRect(o){
for(var r = {l: o.offsetLeft, t: o.offsetTop, w: o.offsetWidth, h:
o.offsetHeight};
o = o.offsetParent; r.l += o.offsetLeft, r.t += o.offsetTop);
return r;
}

var list = document.getElementsByTagName(tagName), i = list.length,
lowest = i ? {o: list[0], r: getRect(list[0])} : {o: null, r: {l: 0,
t: 0, w: 0, h: 0}};
for(var r = lowest.r, y = r.t + r.h; i; (r = getRect(list[--i])).t +
r.h > y && (lowest = {o: list, r: r}, y = r.t + r.h));
return lowest;
}


I have some difficulties rewriting your last loop...

In searching for lowest, can you help me to modify it, so
it skips the div with a specific id?

Like: if (list.id == 'footer')
// Don't count this as lowest...

TIA...
 
R

RobG

Dag said:
Dag Sunde escreveu:
And at some point, I want the x-coordinate of the bottom
edge of the element that is lowest down on the page.

If you have no way to keep the lowest <div> safe, like "if(newDiv <
lowest) lowest = newDiv", then I can't see a nice way to do it (without
loop) :)

Try the code bellow, I didn't tested much... =/

function getLowestDown(tagName){
function getRect(o){
for(var r = {l: o.offsetLeft, t: o.offsetTop, w: o.offsetWidth, h:
o.offsetHeight};
o = o.offsetParent; r.l += o.offsetLeft, r.t += o.offsetTop);
return r;
}

var list = document.getElementsByTagName(tagName), i = list.length,
lowest = i ? {o: list[0], r: getRect(list[0])} : {o: null, r: {l: 0,
t: 0, w: 0, h: 0}};
for(var r = lowest.r, y = r.t + r.h; i; (r = getRect(list[--i])).t +
r.h > y && (lowest = {o: list, r: r}, y = r.t + r.h));
return lowest;
}



I have some difficulties rewriting your last loop...

In searching for lowest, can you help me to modify it, so
it skips the div with a specific id?

Like: if (list.id == 'footer')
// Don't count this as lowest...


Using the above script and simplifying somewhat, try the version
below. There's no feature testing, required features may not be
supported on all browsers and it won't degrade gracefully if they aren't.


<!-- These divs won't be skipped -->
<div id="diva" style="height: 30px; border: 1px solid red;">diva</div>
<div id="divb" style="height: 30px; border: 1px solid red;">divb</div>
<div id="divc" style="height: 30px; border: 1px solid red;">divc</div>
<div id="divd" style="height: 30px; border: 1px solid red;">divd</div>

<!-- This div will be skipped -->
<div id="divz" style="height: 30px; border: 1px solid red;">divz</div>


<script type="text/javascript">

// Div id's not to include
var divsToSkip = {divx:0, divz:0};

function getLowestDown(tagName)
{
function getBottom(o)
{
var b = 0;
while (o.offsetParent){
b += o.offsetTop;
b += o.offsetHeight;
o = o.offsetParent;
}
return b;
}

var list = document.getElementsByTagName(tagName);
var i = list.length;
var lowest = {o: null, b:0};
var t = {};
while (i--){
t = { o: list, b: getBottom(list)};

// Check if lower and if id is not in divs to skip
if ( t.b>lowest.b && !(t.o.id && (t.o.id in divsToSkip))) {
lowest.o = t.o;
lowest.b = t.b;
}
}
return lowest;
}

var x = getLowestDown('div');

alert('Lowest: ' + x.o.nodeName + ' '
+ (x.o.id || '') + '\n'
+ 'Bottom: ' + x.b);

</script>
 
D

Dag Sunde

RobG said:
Dag said:
Dag Sunde escreveu:

And at some point, I want the x-coordinate of the bottom
edge of the element that is lowest down on the page.
<snipped
var list = document.getElementsByTagName(tagName), i = list.length,
lowest = i ? {o: list[0], r: getRect(list[0])} : {o: null, r: {l: 0,
t: 0, w: 0, h: 0}};
for(var r = lowest.r, y = r.t + r.h; i; (r = getRect(list[--i])).t +
r.h > y && (lowest = {o: list, r: r}, y = r.t + r.h));
return lowest;
}



I have some difficulties rewriting your last loop...

In searching for lowest, can you help me to modify it, so
it skips the div with a specific id?

<script type="text/javascript">

// Div id's not to include
var divsToSkip = {divx:0, divz:0};

function getLowestDown(tagName)
{
function getBottom(o)
{
var b = 0;
while (o.offsetParent){
b += o.offsetTop;
b += o.offsetHeight;
o = o.offsetParent;
}
return b;
}

var list = document.getElementsByTagName(tagName);
var i = list.length;
var lowest = {o: null, b:0};
var t = {};
while (i--){
t = { o: list, b: getBottom(list)};

// Check if lower and if id is not in divs to skip
if ( t.b>lowest.b && !(t.o.id && (t.o.id in divsToSkip))) {
lowest.o = t.o;
lowest.b = t.b;
}
}
return lowest;
}


This is almost perfect...

My problem is that this solution (getBottom(...)) doesn't take into
consideration if o is absolute or relatively positioned.

The bottom line is that with the chaos of positioning in the page at hand,
the final lowest returned is added up to a too high value...

Any hints?
 
R

RobG

Dag Sunde wrote:
[...]
This is almost perfect...

My problem is that this solution (getBottom(...)) doesn't take into
consideration if o is absolute or relatively positioned.

The bottom line is that with the chaos of positioning in the page at hand,
the final lowest returned is added up to a too high value...

Any hints?

Posting some (simple :) ) test cases would help (or a link).

You may not be able to cover every situation, but you might be able to
cover a sufficient subset that suits your particular purpose (dang,
ain't alliteration grand!).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top