views:

207

answers:

2

I need to determine if an HTML element is nested inside an element that is positioned absolutely. (1)*

e.g. I can do this:

function hasAbsoluteAncestor(obj){
  while(obj != null){
    if(window.getComputedStyle(obj,null).position == 'absolute'){
      return true;
    } else {
      obj = obj.offsetParent;
    }
  }
  return false;
}
//yes I'm aware IE doesn't play by the W3C game here...  but I have a separate
//IE fix to enable this method in IE
//I'm also aware the above checks the "test" element too (ignore that for now)

but it seems fairly expensive to test for a rare case. I'm guessing 95% of the time it will be a tree of relative elements.

Is there any indicators that an element is nested in such a hierarchy? Any neat hacks that anyone knows?

Update: Based on Peter's comments about premature optimization I've altered my logic to return the coordinates to return 2 pairs... 1 pair (x,y) up to the root, another pair up the the first absolutely positioned parent. It still "feels" dirty, but doesn't appear to have any major impact to performance.

(1)* Why do I need this? I am adding a new absolutely positioned element below the tested element, setting the .left and .top properties... which (if) an ancestor is absolutely positioned, is the offset from that ancestor, not from the body/viewport thus I need to know if I need the position of the tested element as coordinates, realative to the body or a particular ancestor.

A: 

"Seems" fairly expensive? This sounds an awful lot like premature optimization to me.

Do you know it's expensive? Have you tested it?

I'm actually willing to bet that it's not terribly expensive. Even on really complex HTML pages with really deep nodes, what are we talking about here - 30 iterations? 40?

IMHO, optimize when you need to - i.e., when your testing indicates that there's an issue.

Peter Bailey
quite true... my issue is that I don't know how my test element is nested, without checking... depending on the results of the check, I either need to walk back up the partial tree to get the combined horizontal/vertical offset to the "absolute" element... or all the way back to the root. I want to see if I can avoid 2 walks up the tree if I can.
scunliffe
A: 

I can't imagine walking up the ancestor tree would take much time, compared to the overhead of doing something to the DOM.

In jQuery, I'd probably compare position() and offset() of the immediate ancestor only, if I understand your need correctly. Not sure how those are implemented, but they make take advantage of some trick you don't know of.

Nosredna
unfortunately on this environment I don't have access to jQuery :-(
scunliffe
But perhaps you could look at the jQuery source and see how they get position and offset, because it seems like you're interested in when they diverge.
Nosredna