admin管理员组

文章数量:1178538

I'm building a single page website with the top bar navigation linking to different sections on the page. I've linked it up using Scrollspy as <body data-spy="scroll" data-offset="50" id="home">. That works great. Each section is highlighted in the navigation.

The problem lies with the final section. Because it is a short section and does not fill the entire page the id="contact" is never reached, and therefore the navigation element is not highlighted.

I notice that on the bootstrap examples page when you reach the final element it is highlighted before its id is reached - yet the id is at the top of the section just like all the other sections.

I've had a look through the custom application.js file but don't see anything relating to scrollspy behaviour.

Can anyone shed any light on it?

I'm building a single page website with the top bar navigation linking to different sections on the page. I've linked it up using Scrollspy as <body data-spy="scroll" data-offset="50" id="home">. That works great. Each section is highlighted in the navigation.

The problem lies with the final section. Because it is a short section and does not fill the entire page the id="contact" is never reached, and therefore the navigation element is not highlighted.

I notice that on the bootstrap examples page when you reach the final element it is highlighted before its id is reached - yet the id is at the top of the section just like all the other sections.

I've had a look through the custom application.js file but don't see anything relating to scrollspy behaviour.

Can anyone shed any light on it?

Share Improve this question edited May 15, 2014 at 8:29 deadlyhifi asked Mar 23, 2012 at 14:45 deadlyhifideadlyhifi 6077 silver badges16 bronze badges
Add a comment  | 

8 Answers 8

Reset to default 11

For some this issue could be due to a quirks/DOCTYPE issue. If your scroll area is on the body, then scrollspy will calculate viewport height off of the window object. If you are using jQuery 1.8.2 and you do not have the proper DOCTYPE set, then the scrollspy calculation for viewport height will return the total height causing the last item to always be selected.

If you switch back to jQuery 1.7.2 like on http://twitter.github.com/bootstrap/javascript.html then it will work again, or you can set the proper DOCTYPE.

Here is more info on the "notabug" issue : http://bugs.jquery.com/ticket/12426

I was just looking for the answer to this myself. The bootstrap demo page was definitely doing something different than my page when it came to the last item. I too looked through application.js but didn't see anything. Finally I decided to compare their version of scrollspy.js and mine. They are using v2.0.4 while I had v2.0.2. I replaced my version with the new and it just started working as expected.

Then I referred to the bootstrap changelog and found out that v2.0.3 was released on April 24, 2012. One of the changes listed was "Always select last item in scrollspy if you've reached the bottom of the document or element".

So I guess they quietly fixed it internally since I downloaded bootstrap. You may have already figured this out too, but hopefully it will help others looking for the same answer.

Just increase your data-offset attribute to something larger like 500, like so:

<body data-spy="scroll" data-offset="500" id="home">

The bootstrap demo works fine because it is also offsetting the height of the subnav, along with the 50px offset that is given on the data attribute.

I have a workaround. On line 40 of twitter's scrollspy JS, you'll see:

this.process()

Just remove that. This runs the process method in a clever attempt to start 'er up. But this is processed when you scroll anyways, so just remove it and you should be good.

Adding the HTML doctype declaration to the top of the page fixed it for me:

<!DOCTYPE html>

In my case it only works if I set the scrollable data container to the <body> element.

I use a smooth scroll script combined with it and it works great:

$('.sub-nav-collapse .nav li a').live('click',function(event) {
    event.preventDefault();
    $('html, body').animate({scrollTop: $($(this).attr('href')).offset().top-70}, 500);
});

Hope that helps someone!

Cheers!

Using jQuery 1.8.3 and an html5 doctype, I found that having a viewport initial scale of 1 caused scrollspy to fail:

<meta name="viewport" content="width=device-width, initial-scale=1">

I removed the reference to initial-scale=1 and scrollspy started working.

I've found this question looking for solution for my problem. Scrollspy worked fine until it reached last 4 sections. When it happened it jumped immediately to the last sections avoiding 3 others on his way. It was caused by relatively small sizes of those sections. Thanks to Jon's answer I decided to investigate scrollspy script and I found the following lines:

if (scrollTop >= maxScroll) {
    return activeTarget != (i = targets.last()[0])
    && this.activate ( i )
}

They are responsible to select last section if the end of page is reached. Commenting them may help in cases like mine (jumping 3 sections at once), but it prevents from reaching the last section if it is to small.

本文标签: javascripttwitter Bootstrap Scrollspy highlight final elementStack Overflow