Skip to content

Instantly share code, notes, and snippets.

@atk
Forked from 140bytes/LICENSE.txt
Last active December 18, 2015 02:39
Show Gist options
  • Save atk/5712997 to your computer and use it in GitHub Desktop.
Save atk/5712997 to your computer and use it in GitHub Desktop.
Offset

Offset

Will return an object that at least have a "left" and a "top" property. If the getBoundingClientRect method is present, the position will be relative to the viewpoint, otherwise it will be absolute, so the results will only coincide if the viewport is 0,0 (initial page load should suffice). In some circumstances, the fallback will be imprecise, but you can only do so much with 138 bytes.

Thanks to @jbebe for inspiring me to the recursive approach and to @jed for having this funny little challenge with me.

function o(
a,
x,
y,
z
){
// if a is present and supports the getBoundingClient method
return a && a[z='getBoundingClientRect'] ?
// use it
a[z]() :
// otherwise check if a is present
// (document.body.offsetParent === null)
a ?
// if yes, recursively call
o(
// with the offset parent
a.offsetParent,
// and a normalized x
~~x+~~a.offsetLeft,
// and y value increased by the relative offset
~~y+~~a.offsetTop
) :
// otherwise return the offset object composed from x and y
{ left: x, top: y }
}
function o(a,x,y,z){return a&&a[z='getBoundingClientRect']?a[z]():a?o(a.offsetParent,~~x+~~a.offsetLeft,~~y+~~a.offsetTop):{left:x,top:y}}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2013 Alex Kloss <[email protected]>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "offset",
"description": "Primitive DOM offset function with fallback for getBoundingClientRect",
"keywords": [
"DOM",
"node",
"offset",
"fallback",
"getBoundingClientRect"
]
}
<!DOCTYPE html>
<title>Foo</title>
<div>Expected value: <b>left: x, top: y</b> (values may differ depending on browser/-settings)</div>
<div>Actual value: <b id="ret"></b></div>
<script>
function o(a,x,y,z){return a&&a[z='getBoundingClientRect']?a[z]():a?o(a.offsetParent,~~x+~~a.offsetLeft,~~y+~~a.offsetTop):{left:x,top:y}}
var ret = document.getElementById( "ret" ), offset = o(ret);
ret.innerHTML = 'left: '+offset.left+', top: '+offset.top;
</script>
@atk
Copy link
Author

atk commented Jun 5, 2013

If you want to account for the viewport position, use the rather longer variant:

function o(a,x,y,z){return a&&a[z='getBoundingClientRect']&&(a=a[z](),z=document.documentElement)?{left:(this.pageXOffset||z.scrollLeft)+a.left,top:(this.pageYOffset||z.scrollTop)+a.top}:a?o(a.offsetParent,~~x+~~a.offsetLeft,~~y+~~a.offsetTop):{left:x,top:y}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment