Scroll to snap and hold nav

I am trying to make fixed link navigation fixed when scrolling to an anchor. Eliminating scroll to anchor is not a problem.

The problem is that my navigator is almost at the bottom of the screen. So what happens if you scroll down, the navigation will get a class fixed. When you click on the binding link, the script scrolls far to the binding block. I tried to compensate for navigation to the height of navigation. This works, but only when you click the same link a second time. The first click on the anchor link still makes the link too far!

I created a script to explain what happens → Fiddle

I personally believe that scrollTo and the simultaneous creation of a navigator interfere with each other.

Does anyone know what can do this?

What I have:

<div class="anchor-links">
    <div class="anchor-wrapper">
        <ul class="nav-list">
            <li><a href="#description" class="goSmoothly">Product information</a></li>
            <li><a href="#bundles" class="goSmoothly">Product bundles</a></li>
            <li><a href="#reviews" class="goSmoothly">Reviews</a></li>
            <li><a href="#related" class="goSmoothly">Related products</a></li>
        </ul>
    </div>
</div>

<div id="description" class="block">description</div>
<div id="bundles" class="block">bundles</div>
<div id="reviews" class="block">reviews</div>
<div id="related" class="block">related</div>

var fixmeTop = $('.anchor-links').offset().top;

$(window).scroll(function() {
    var currentScroll = $(window).scrollTop();
    if (currentScroll >= fixmeTop){
        $('.anchor-links').addClass("sticky");
    } else {
        $('.anchor-links').removeClass("sticky");
    }
});

$('.goSmoothly').click(function(event){     
    event.preventDefault();
    $(this).addClass('active');
    $('html,body').animate({
        scrollTop: $(this.hash).offset().top - 100
    }, 500);
});
+4
source share
2 answers

Try it.

var fixmeTop = $('.anchor-links').offset().top;

$(window).scroll(function() {
    var currentScroll = $(window).scrollTop();
    if (currentScroll >= fixmeTop){
        $('.anchor-links').addClass("sticky");
    } else {
        $('.anchor-links').removeClass("sticky");
    }
});

$('.goSmoothly').click(function(event){		
    event.preventDefault();
    $(this).addClass('active');
    if( $('.anchor-links').hasClass("sticky")) {
    $('html,body').animate({
        scrollTop: $(this.hash).offset().top - 100
    }, 500);
    } else {
    $('html,body').animate({
        scrollTop: $(this.hash).offset().top - 220
    }, 500);    
    }
});
.block{
    height:700px;
    background:#eee;
}
.anchor-links {
  border-bottom: 1px solid #f5f5f5;
  border-top: 1px solid #f5f5f5;
  margin-bottom: 20px;
}
.anchor-links .nav-list li {
  display: inline-block;
  line-height: 4.2rem;
}
.anchor-links.sticky {
  background: #fff none repeat scroll 0 0;
  border-bottom: 1px solid #f5f5f5;
  left: 0;
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 99;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img width="400" height="400" alt="Adidas 2 Opties" itemprop="image" class="featured" data-original-url="http://static.webshopapp.com/shops/057743/files/029936946/adidas-2-opties.jpg" src="http://static.webshopapp.com/shops/057743/files/029936946/400x400x2/adidas-2-opties.jpg">
<div class="anchor-links">
    <div class="anchor-wrapper">
        <ul class="nav-list">
            <li><a href="#description" class="goSmoothly">Product information</a></li>
            <li><a href="#bundles" class="goSmoothly">Product bundles</a></li>
            <li><a href="#reviews" class="goSmoothly">Reviews</a></li>
            <li><a href="#related" class="goSmoothly">Related products</a></li>
        </ul>
    </div>
</div>

<div id="description" class="block">description</div>
<div id="bundles" class="block">bundles</div>
<div id="reviews" class="block">reviews</div>
<div id="related" class="block">related</div>
Run codeHide result

Now, on the other, you can make -220 a dynamic size headerbefore correcting it smaller than the header size after fixing it.

As I told you in the comment, the fact that you remove the title from the body and fix it reduces the top of the scroll bar of each section.

You also have the option to add a placeholder when the title is fixed, this way you will prevent math clutter.

+1
source

This seems to work: JSfiddle .

HTML:

<div class="anchor-links">
    <div class="anchor-wrapper">
        <ul class="nav-list">
            <li><a href="#description" class="goSmoothly">Product information</a></li>
            <li><a href="#bundles" class="goSmoothly">Product bundles</a></li>
            <li><a href="#reviews" class="goSmoothly">Reviews</a></li>
            <li><a href="#related" class="goSmoothly">Related products</a></li>
        </ul>
    </div>
</div>
<div class="container">
<div id="description" class="block">description</div>
<div id="bundles" class="block">bundles</div>
<div id="reviews" class="block">reviews</div>
<div id="related" class="block">related</div>
</div>

CSS

.container {
    margin-top: 100px;
}
.block{
    height:700px;
    background:#eee;
}
.anchor-links {
  border-bottom: 1px solid #f5f5f5;
  border-top: 1px solid #f5f5f5;
  margin-bottom: 20px;
  position: fixed;
  top:0;
  left: 0;
  background: #fff;
  width: 100%;
}
.anchor-links .nav-list li {
  display: inline-block;
  line-height: 4.2rem;
}
.anchor-links.sticky {
  background: #fff none repeat scroll 0 0;
  border-bottom: 1px solid #f5f5f5;
  left: 0;
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 99;
}
+1
source

All Articles