Reputation: 1373
I essentially have an unordered list of list items in a div that doesn't scroll to the next element properly. I'm just trying to have a button to scroll up and down the list.
While the code does scroll, it doesn't match up with the li
elements. After every click, it scrolls up a little bit, then down on the next click. I've tried walking the DOM and verifying the element it is scrolling to is an li
element, but didn't see the issue.
I have the following jsfiddle: http://jsfiddle.net/YD9s5/9/
The elements are:
photos-div
photos-li
(whoops, leaving it for now)photo-li-X
where X is a numberThe code being used to scroll the div is:
$('#photos-div').scrollTop($('#photo-li-' + i).offset().top);
The i
variable is being incremented, as you can see.
Upvotes: 3
Views: 5334
Reputation: 92893
The problem is that .offset()
gets the position of an element relative to the entire document, and that position is constantly moving up. So once you've scrolled to item 1, it returns the .offset().top
that item 1 currently has in the document, which is now where item 0 used to be.
Add console.log( $('#photo-li-0').offset() );
to the top of your scrollToElement()
function and you'll see what I mean. Notice that the top offset keeps decreasing, quickly moving into the negative numbers as it moves off the top of the document.
The fix is to take the difference between the offset of $('#photo-li-'+i)
and $('#photo-li-0')
(or the container $('#photos-li')
itself) and scroll to that instead:
var newpos = $('#photo-li-' + i).offset().top - $('#photo-li-0').offset().top;
$('#photos-div').scrollTop(newpos);
http://jsfiddle.net/mblase75/x4hQP/ (incorporates other improvements)
Upvotes: 6
Reputation: 3661
It appears that .offset()
only measures from the top of the document. You are interested in how far the element is from the top of #photos-div
. Here's a working version where I track the position in the div manually. Notice in the console that when I log the value of .offset()
it's relative to the document rather than the scrolling div.
Seems that there should be a way to do this without carrying the position of that div in state. Working on it...
Here's my more programatic solution.
Upvotes: 0