开发者

How do you calculate the page position of a dom element when the body can be relative positioned?

开发者 https://www.devze.com 2023-02-23 07:48 出处:网络
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).

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消