How do you calculate the page position of a dom element when the body can be relative positioned?
I have a weird bug that started showing up when I made the body be a relative positioned element with a 39px margin (I'm making room for a toolbar at the top of a page).
Anyway - if you look at how most sites tell you to compute a page element position, you'll see code like this:
function getPos(elt) {
var pt = [0, 0];
while (elt.offsetParent !== null) {
pt[0] += elt.offsetLeft;
pt[1] += elt.offsetTop;
elt = elt.offsetParent;
}
return pt;
}
This works fine, even if your <body> tag has a a margin. BUT, if your body is also position:relative, then this returns a value with is too small - it does not include the margins of the body element.
How do I 1) detect if the body is relative p开发者_运维技巧ositioned, and 2) find our what the margins are so I can add them back in?
Note that I need Page coordinates so I can compare them to MouseEvent PageX, PageY.
If you restrict yourself to only working in "modern" browsers, as the zepto.js implementation does, you can get a much smaller implementation of the .offset() function:
offset: function(){
var obj = this[0].getBoundingClientRect();
return {
left: obj.left + document.body.scrollLeft,
top: obj.top + document.body.scrollTop,
width: obj.width,
height: obj.height
};
}
https://github.com/madrobby/zepto/blob/master/src/zepto.js
Which is more or less what jQuery does if getBoundingClientRect is available.
OK, I just did more research on this. The short answer, use jQuery:
$(elt).offset()
This is an a complex area that jQuery has a lot of code to handle all the cases correctly (see https://github.com/jquery/jquery/blob/master/src/offset.js). I think most browsers support getClientBoundingRect - in which case jQuery will use that (but has to adjust for viewport scroll position). Otherwise, it adjusts for the computed style of the body (yes, $(elt).css('margin-left') will return the computed style), as well as any borders on intervening elements.
So, the long answer is - unless you want to re-invent the 100+ lines of code from jQuery or other framework - best to get this measurement using their code, rather than write your own.
Here's a fiddler show some of the other methods (expanded from Snake Faust's - thanks!):
http://jsfiddle.net/mckoss/9zLGt/
BTW, Snake, the offset from parent containers is $(elt).position(); $(elt).offset() returns the offset relative to the page/document - which is what I am looking for here.
精彩评论