26

I cannot quite get the scroll spy to work properly with a vertical nav. Below you can find the code I use. For some reason, only "Two" gets active.

Anyone has an idea as of what is wrong?

<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Twitter Bootstrap Scroll Spy Playground</title>
    <link href="bootstrap/css/bootstrap.css" rel="stylesheet">
  </head>
  <body>
    <div class="container">
      <div class="row">
        <div class="span3">
            <ul class="navbar nav nav-list affix">
              <li class="active"><a href="#one">One</a></li>
              <li><a href="#two">Two</a></li>
            </ul>
        </div>
        <div class="span1" data-spy="scroll">
            <section id="one">
            <h1>One</h1>
            <h2>Ad leggings keytar, brunch id art party dolor labore. Pitchfork yr enim lo-fi before they sold out qui. Tumblr farm-to-table bicycle rights whatever. </h2>
            </section>
            <section id="two">
            <h1>Two</h1>
           <h2>Anim keffiyeh carles cardigan. Velit seitan mcsweeney's photo booth 3 wolf moon irure. Nihil tattooed accusamus, cred irony biodiesel keffiyeh artisan ullamco consequat.</h2>
            </section>   
        </div>
      </div>
    </div>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script src="bootstrap/js/bootstrap.js"></script>
</body>
</html>
cvrebert
  • 9,075
  • 2
  • 38
  • 49
user1780429
  • 306
  • 1
  • 3
  • 6

9 Answers9

36

In sorting this out for myself, I've found that the element being spied upon needs to have a scroll bar.

Take a look at this Fiddle: http://jsfiddle.net/adamp/qgU6h/1/

You can either spy directly on the body element ($('body').scrollspy()) or give your content an explicit height and force it to show a scrollbar.

(If you look at the Bootstrap documentation example, it does the fixed-height trick.)

adam-p
  • 660
  • 6
  • 16
  • **documentation example** link is dead, you can find it [here](http://twitter.github.io/bootstrap/2.3.2/javascript.html#scrollspy) now. – Kamran Ahmed Jul 28 '13 at 09:46
  • 2
    +1 for the "spied element needs to have a scroll bar", that's what made the trick for me! – David Sep 25 '13 at 07:12
  • Hmm, I tried in ie/ff/chrome and the fiddle doesn't seem to work for me. Am I crazy? "Page1", "Page2" etc titles do not light up or highlight in any way as i scroll up / down. – Shaun Rowan Oct 17 '13 at 03:24
  • @ShaunRowan: The URL to the externally linked `bootstrap-scrollspy.js` had broken, so the whole thing didn't work. I fixed the Fiddle and I believe it should work fine again. – adam-p Oct 18 '13 at 17:34
  • It's worth noting that scrollspy **only** works with [navs](http://getbootstrap.com/2.3.2/components.html#navs) and [navbars](http://getbootstrap.com/2.3.2/components.html#navbar). Changing the class `nav` to `nav2` will break the above fiddle: http://jsfiddle.net/r78U9 – Kevin Jurkowski Nov 08 '13 at 01:30
  • And that if you activate scrollspy via JS, you _don't need to have a scroll bar_: http://jsfiddle.net/Ra3EM – Kevin Jurkowski Nov 08 '13 at 01:37
  • The link to the documentation is to Bootstrap 2, which is out of date. [Here](http://getbootstrap.com/javascript/#scrollspy) is the updated link – xavdid Oct 15 '15 at 22:12
2

you can do this like http://jsfiddle.net/mCxqY/

<body data-spy="scroll" data-target="#navbar">
    <div id="post1" class="box">
        <h1>Post 1</h1>
        <p> Scroll Down↓</p>
    </div>
    <div id="post2" class="box"><h1>Post 2</h1></div>
    <div id="post3" class="box"><h1>Post 3</h1></div>

    <div id="navbar">
        <ul class="nav">
            <li><a href="#post1">Post 1</a></li>
            <li><a href="#post2">Post 2</a></li>
            <li><a href="#post3">Post 3</a></li>
        </ul>
    </div>

    <script src="http://twitter.github.com/bootstrap/assets/js/bootstrap-scrollspy.js"></script>
</body>​

css

@import url(http://twitter.github.com/bootstrap/assets/css/bootstrap.css);
.box{
    margin: 20px; padding: 15px;
    background: #eee;
    height: 500px;
}
#navbar{
    position: fixed;
    bottom: 0; left: 20px;
    width: 100%;
    background: #fff;
}
.nav li a{
    float: left;
    width: 80px;
    padding: 15px 0;
}
.nav li a:hover{
    color: #f33 !important;
    background: none;
}
.nav li.active a{
    color: #f55;
    text-decoration: underline;
}

NullPoiиteя
  • 56,591
  • 22
  • 125
  • 143
  • Thanks for the reply. However, I still do not know what is wrong with the original code. – user1780429 Nov 01 '12 at 08:51
  • Actually, I tried to extract your example into a standalone file, and it does not work for me. See here: https://dl.dropbox.com/u/18323746/Tmp/html-playground/try-stakoverflow-answer-original.html – user1780429 Nov 01 '12 at 08:53
  • @ShaunRowan me too, maybe the bootstrap.js of demo is too old, I change the bootstrap.js and it works fine http://jsfiddle.net/yujiangshui/mCxqY/313/ – Harry Yu Jan 03 '15 at 07:18
2

Thanks Jerreck I was able to make mine works with the help of

height: 100%;

in the body selector of my CSS

Also as recommended by the guys at Bootstrap http://getbootstrap.com/javascript/#scrollspy

I've added position: relative; in the body too.

The beginning of the body selector in my CSS goes like this:

body {
    position: relative;
    height: 100%;
    /* … */
}

In the <body> in HTML I had to remove

data-offset="0"

so it is now like this

<body data-spy="scroll" data-target="#navigation">
Volker E.
  • 5,911
  • 11
  • 47
  • 64
1

I had to do two things to get scrollspy to work for me.

First, I had to give a height to the <body> element:

<style>

  .body
  {
    height: 100%;
  }

</style>    

<body data-spy="scroll" data-target="#scrollElement" data-offset="0">

I think this is because scroll-spy is trying to get the height of the element that you're spying on, but if there isn't a height specified for your element, it gets passed a null (or 0?) value, which seems to be breaking the script's calculations.

Second, I had to make sure that there was enough vertical space between my id elements (that the nav anchors are pointing towards).

I couldn't figure out the exact amount of space necessary (it did vary depending on the data-offset attribute, so it probably has something to do with that), but I reckon that if you have a height set to your spy element and scrollspy still isn't working - just add more content between your id elements.

Jerreck
  • 2,930
  • 3
  • 24
  • 42
1

I did it like this. for data target I use the class name .navbar

      <body data-spy="scroll" data-target=".navbar" data-offset="50">
       <nav class="navbar navbar-default navbar-fixed-top" >
Ayush Chaurasia
  • 345
  • 4
  • 9
0

After hours of frustration and research, I came to find that many people are also not pleased with Bootstrap Affix's documentation (www.mtjhax.wordpress.com). After all the looking around though, this solution on Bootply worked for me: http://bootply.com/63937

Say your navigation had the id "navbar", the body should look like this:

<body data-spy="scroll" data-target="#navbar">
    ...
</body>

And the navbar itself should be as follows:

<div class="navbar" id="navbar">
    <ul class="nav navbar-nav">
        <li>...</li>
        <li>...</li>
        <li>...</li>
    </ul>               
</div>

You then initialized the plugin...

$('#nav').affix({
    offset: {top: 0}
}); 

... and give the navigation proper styling:

#nav.affix {
    position: fixed;
    top: 0;
    width: 100%
}
Carol Skelly
  • 351,302
  • 90
  • 710
  • 624
radu.luchian
  • 279
  • 1
  • 5
  • 21
0
$(window).scroll(function() {
    if ($(".navbar").offset().top > 50) {
        $(".navbar-fixed-top").addClass("top-nav-collapse");
    } else {
        $(".navbar-fixed-top").removeClass("top-nav-collapse");
    }
});

//jQuery for page scrolling feature - requires jQuery Easing plugin
$(function() {
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top
        }, 1500, 'easeInOutExpo');
        event.preventDefault();
    });
});
0
.nameClasse {
  position: relative;
  overflow: auto;
  height: 330px;
}

<div data-spy="scroll" data-target="#navbarVertical" data-offset="0" class="nameClass">
ice1000
  • 6,406
  • 4
  • 39
  • 85
  • Welcome to Stack Overflow! Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others. – Tim Diekmann May 27 '18 at 00:26
0

Consider using the HxScrollspy component based on Bootstrap 5.

Robert Haken
  • 132
  • 1
  • 5