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

I have a strange error that began to appear when I made the body a relative positioned element with an edge of 39 pixels (I take up space for the toolbar at the top of the page).

In any case, if you look at how most sites tell you to calculate the position of a page element, you will see the following code:

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 margin. BUT, if your body is also a position: relative, then this returns a value too small - it does not include the fields of the body element.

How to 1) determine whether the body is relative, and 2) find our fields so that I can add them back?

Note that I need the page coordinates, so I can compare them with MouseEvent PageX, PageY.

+6
javascript html css
Apr 08 '11 at 23:10
source share
3 answers

OK, I just did more research on this. Short answer, use jQuery:

 $(elt).offset() 

This is a complex area in which jQuery has a lot of code to handle all cases correctly (see https://github.com/jquery/jquery/blob/master/src/offset.js ). I think most browsers support getClientBoundingRect - in this case jQuery will use this (but should adjust the scroll position in the viewport). Otherwise, it is configured for the calculated body style (yes, $ (elt) .css ("margin-left") will return the calculated style), as well as any borders for intermediate elements.

So, the long answer is - if you do not want to reinvent more than 100 lines of code from jQuery or another structure - it is best to get this dimension using your code, rather than writing your own.

Here the violinist shows some other methods (extended from Snake Faust - thanks!):

http://jsfiddle.net/mckoss/9zLGt/

BTW, Snake, offset from parent containers - $ (elt) .position (); $ (elt) .offset () returns the offset relative to the page / document - this is what I am looking for here.

+4
Apr 09 2018-11-11T00:
source share

If you restrict yourself to 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

More or less what jQuery does if getBoundingClientRect is available.

+14
Apr 11 '11 at 18:27
source share

If you use a JavaScript framework like jQuery, most of them are pretty simple.

If you are not familiar with any js frameworks, I would prioritize learning. They (at least jQuery) do not force you to use any of their constructs, so including a framework (just calling the jquery library) is unlikely to interfere with any js that you have already written.

The following code is also available for viewing and is demonstrated at http://jsfiddle.net/Z6VkD/ :

HTML:

 <div id="tester"></div> 

JavaScript (jQuery):

 var bodyPositioning = $("body").css("position"); var bodyMargin = $("body").css("margin-left"); $("#tester").append("<p>body positioning: <b>"+bodyPositioning+"</b></p>" ); $("#tester").append("<p>body margin-left:<b>"+bodyMargin+"</b></p>"); 

CSS

 body{position:relative;margin-left:100px;} #tester{height:100px;width:300px;border:3px solid green;} 

You cannot directly calculate the body offset from the viewport (w / jQuery), but capturing field values ​​should work, since there is no container for the body. BTW. For offsets from parent containers, you can use the jQuery.offset () method (see offset () - jQuery API )

In any case, I would recommend not placing the fields on your body and creating a wrapper for everything inside the body and instead adding fields to this element. Thus, you can apply background styles on the body, which, if necessary, will cover the entire width of the viewport.

0
Apr 09 '11 at 8:13
source share



All Articles