Reputation: 77416
Let's say that I have a div $container
with position: relative
, and a div $foo
within it with position: absolute
. I want to get the position of $foo
relative to the container. jQuery makes this easy:
$foo.position()
which returns an object with top
and left
properties, specified in pixels. The problem is, this number is no longer accurate if the container is scrolled down or to the right at all. Specifically, it changes, when it shouldn't. jQuery computes position()
such that it's equivalent to $foo.offset() - $container.offset()
(where offset()
gives the window-relative position), and $foo.offset()
changes as the user scrolls around $container
.
Upvotes: 2
Views: 1722
Reputation: 195992
Add the .scrollLeft()
and .scrollTop()
of the $container
to the values returned by the .position()
of the $foo
That should cover it ..
Update
To find the relative parent you should use the following
var $parent = $foo.parents()
.filter(
function(){
var position = $(this).css('position')
return position==='relative' || position==='absolute';
}
).eq(0);
Upvotes: 0
Reputation: 77416
It seems you need to take $foo.position()
and then adjust is by adding $container
's scrollTop()
and scrollLeft()
.
This becomes annoying if you don't actually know what $foo
's relative container is. I've resorted to writing a function (in CoffeeScript):
$.fn.container: ->
$parent: @parent()
if $parent.css('position') is 'relative'
return $parent
else
return $parent.container()
Is there a more direct way that I'm overlooking? Or a direct way of finding an arbitrary element's container's scrollbar positions?
[Update: After reading Gaby's answer and comments, I cooked up a small jQuery plugin that goes through all of an element's parents and adds their scrollTop()
and scrollLeft()
to that element's position()
. I haven't tested this thoroughly, so please try it and let me know if it works for you: jqPositionWithScrolling plugin
It's a little odd that position()
doesn't do this automatically—I'd dare call it a bug.]
Upvotes: 1