Reputation: 14250
I am trying to create a small feature that user can click the left nav
link and the right div will scroll to correspond box.
For example, user clicks second link, the right div
will scroll to the second box
inside that div
.
Here is the HTML:
<div id='nav'>
<ul>
<li><a id='link1' class='link' href='#'>test 1</a><li>
<li><a id='link2' href='#'>test 2</a><li>
...
<li><a id='link16' href='#'>test 16</a><li>
</ul>
</div>
<div id='items'>
<div id='link1-test' class='box'>
test 1
</div>
<div id='link2-test' class='box'>
test 2
</div>
...
<div id='link16-test' class='box'>
test 16
</div>
</div>
Here is the javascript:
$('#nav a').on('click', function(){
var id=$(this).attr('id')
alert(id)
$('#items').animate({
scrollTop: $('#'+id+'-test').offset().top
}, 700);
})
My problem is that my codes don't seem to work because the boxes
position inside the right div changes all the time. I am not sure how to solve this and it's been bothering me a while. Can someone please help me out on this? Thanks a lot!
Upvotes: 1
Views: 117
Reputation: 7810
The offset of each div is changing when you scroll the parent div, you just need to adjust for that by getting the target div's offset, and adding the current parent div's scroll position. Just change one line in your code and it will work. Change your scrollTop
option for animate
from this:
scrollTop: $('#'+id+'-test').offset().top
to this:
scrollTop: $('#'+id+'-test').offset().top + $('#items').scrollTop()
Here is a working example: http://jsfiddle.net/BPB7z/7/
Upvotes: 3
Reputation: 6411
Try this: http://jsbin.com/iZUVoBux/1/edit you can see the div has different heights. You should have used .position().top but the value change soon the div is scrolled.
function getOffset(el) {
var _x = 0;
var _y = 0;
while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
_x += el.offsetLeft - el.scrollLeft;
_y += el.offsetTop - el.scrollTop;
el = el.offsetParent;
}
return {
top: _y,
left: _x
};
}
$('#nav a').on('click', function () {
$('#items').animate({
scrollTop: getOffset($('#' + this.id + '-test').get()[0]).top
}, 700);
});
Upvotes: 1