Reputation: 53
Still a noob but I am slowly getting there. I have a series of divs, all the same class and I have previous and next buttons that scroll to the top of the next or previous div when clicked. I would like to set an offset so that my header won't hide the div that scrolls underneath of it and I am unsure how to go about this. Code below.
<button class="prev link js-prev js-scroll-to">Previous</button>
<button class="next link js-next">Next</button>
<script>
$('.js-scroll-to').click(function(e) {
target = $($(this).attr('href'));
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
$('.js-next').click(function(e) {
var selected = $(".js-list-item.js-current-panel");
var anchors = $(".js-list-item");
var pos = anchors.index(selected);
var next = anchors.get(pos+1);
var prev = anchors.get(pos-1);
target = $(next);
$(selected).removeClass("js-current-panel");
$(next).addClass("js-current-panel");
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
$('.js-prev').click(function(e) {
var selected = $(".js-list-item.js-current-panel");
var anchors = $(".js-list-item");
var pos = anchors.index(selected);
var next = anchors.get(pos+1);
var prev = anchors.get(pos-1);
target = $(prev);
$(selected).removeClass("js-current-panel");
$(prev).addClass("js-current-panel");
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
</script>
Upvotes: 2
Views: 512
Reputation: 572
For your case, I think you could just add the offset right into your animated scroll code (subtracting the height of the nav bar plus a little margin):
$('html, body').animate({scrollTop: target.offset().top - 54 + 'px'}, 1000);
I usually do this without a JS scroll by adding a span class to use as the anchor instead of anchoring on the div itself. This will work if someone links directly to the anchor point as well.
That way I can use position relative on the anchor to set an offset for the height of the nav bar.
In this case, I think you probably have some divs like this:
<div class="js-list-item js-current-panel">
content
</div>
<div class="js-list-item">
content
</div>
<div class="js-list-item">
content
</div>
I'd change it to:
<span class="anchor js-list-item js-current-panel"></span>
<div class="content">
content
</div>
<span class="anchor js-list-item"></span>
<div class="content">
content
</div>
<span class="anchor js-list-item"></span>
<div class="content">
content
</div>
With some CSS to position those new anchors (top depends on nav bar height):
.anchor {
position: relative;
top: -54px;
}
Example with some extra CSS to show how the anchors are positioned:
<style type="text/css">
.nav {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 44px;
background: black;
}
.main {
margin-top: 54px;
}
.js-list-item {
display: inline-block;
width: 5px;
height: 5px;
background: blue;
position: relative;
top: -54px;
}
.content {
background: red;
width: 100%;
height: 500px;
margin-bottom: 25px;
}
</style>
<div class="nav">
<button class="prev link js-prev js-scroll-to">Previous</button>
<button class="next link js-next">Next</button>
</div>
<div class="main">
<span class="js-list-item js-current-panel"></span>
<div id="one" class="content">content</div>
<span class="js-list-item"></span>
<div id="two" class="content">content</div>
<span class="js-list-item"></span>
<div id="three" class="content">content</div>
<span class="js-list-item"></span>
<div id="four" class="content">content</div>
<span class="js-list-item"></span>
<div id="five" class="content">content</div>
<span class="js-list-item"></span>
<div id="six" class="content">content</div>
<span class="js-list-item"></span>
<div id="seven" class="content">content</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script>
$('.js-scroll-to').click(function(e) {
target = $($(this).attr('href'));
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
$('.js-next').click(function(e) {
var selected = $(".js-list-item.js-current-panel");
var anchors = $(".js-list-item");
var pos = anchors.index(selected);
var next = anchors.get(pos+1);
var prev = anchors.get(pos-1);
target = $(next);
$(selected).removeClass("js-current-panel");
$(next).addClass("js-current-panel");
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
$('.js-prev').click(function(e) {
var selected = $(".js-list-item.js-current-panel");
var anchors = $(".js-list-item");
var pos = anchors.index(selected);
var next = anchors.get(pos+1);
var prev = anchors.get(pos-1);
target = $(prev);
$(selected).removeClass("js-current-panel");
$(prev).addClass("js-current-panel");
if (target.offset()) {
$('html, body').animate({scrollTop: target.offset().top + 'px'}, 1000);
}
e.preventDefault();
});
</script>
Upvotes: 1