Смещение Bootstrap scrollspy на фиксированной панели навигации не работает

Я создал и точную скрипку моей проблемы здесь для тестирования: http://jsfiddle.net/aVBUy/7/

Проблема в том, что когда я нажимаю на элементы панели навигации, у меня есть скрипт, который прокручивается до идентификатора элемента. И я использую scrollspy, чтобы выделить элементы навигации, когда страница находится в правильном положении. Однако scrollspy меняет активное состояние только тогда, когда попадает в верхнюю часть браузера/устройства. Поскольку моя панель навигации фиксирована, мне нужно смещение, применяемое к scrollspy, для смещения на 51 пиксель (высота панели навигации).

Я пробовал все, и я не могу заставить его работать. Пожалуйста, проверьте мою скрипку и посмотрите, сможете ли вы найти, где я ошибаюсь, это очень мне поможет.

Вот мой минимизированный код...

HTML

<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="navbar-inner">
        <div class="container">
            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </a>
            <a class="brand" href="#"><img src="img/logo.gif" alt="" /></a>
            <div class="nav-collapse collapse">
                <ul class="nav">
                    <li><a href="#welcome" data-scroll="#welcome">Welcome</a></li>
                    <li><a href="#about" data-scroll="#about">About</a></li>
                    <li><a href="#route" data-scroll="#route">The Route</a></li>
                    <li><a href="#bike" data-scroll="#bike">The Bike</a></li>
                </ul>
            </div>
        </div>
    </div>
</div>
<div class="container">
    <div id="welcome" class="row-fluid">
        <div class="span12">
            <h3>Welcome</h3>
            ...
        </div>
    </div>
    <hr />
    <div id="about" class="row-fluid">
        <div class="span12">
            <h3>About the ride</h3>
            ...
        </div>
    </div>
    <hr />
    <div id="route" class="row-fluid">
        <div class="span12">
            <h3>The Route</h3>
            ...
        </div>
    </div>
    <hr />
    <div id="bike" class="row-fluid">
        <div class="span12">
            <h3>The Bike</h3>
            ...
        </div>
    </div>
    <hr>
    <footer>
        <p class="muted"><small>© 2013 All rights reserved.</small></p>
    </footer>
</div>

CSS

body {
    padding: 51px 0 0;
}
/* Override Bootstrap Responsive CSS fixed navbar */
 @media (max-width: 979px) {
    .navbar-fixed-top, .navbar-fixed-bottom {
        position: fixed;
        margin-left: 0px;
        margin-right: 0px;
    }
}
body > .container {
    padding: 0 15px;
}

СЦЕНАРИЙ

var offsetHeight = 51;

$('.nav-collapse').scrollspy({
    offset: offsetHeight
});

$('.navbar li a').click(function (event) {
    var scrollPos = $('body > .container').find($(this).attr('href')).offset().top - offsetHeight;
    $('body,html').animate({
        scrollTop: scrollPos
    }, 500, function () {
        $(".btn-navbar").click();
    });
    return false;
});

СКРИПКА

http://jsfiddle.net/aVBUy/7/


person Joshc    schedule 26.07.2013    source источник


Ответы (6)


Вам нужно применить смещение к телу.

$('body').scrollspy({
   offset: offsetHeight
});

Также вам нужно будет вычесть хотя бы единицу из offsetHeight в строке ниже, иначе не будет работать при прокрутке вверх.

var scrollPos = $('body > .container').find($(this).attr('href')).offset().top - (offsetHeight - 1);
person Schmalzy    schedule 26.07.2013
comment
Я использую offset: $(window).height() * 0.2 - person Nigel Angel; 25.11.2013
comment
Этот ответ мог работать в более старых версиях Bootstrap, но он не работает с Bootstrap 4. К сведению других, которые ищут решение этой проблемы. - person mckenna; 25.04.2019

Вы также можете добиться этого без javascript (через атрибуты данных), объявив data-offset="51" в дополнение к data-target.

Источник: https://getbootstrap.com/docs/3.3/javascript/#scrollspy-usage

person Zoltán    schedule 15.03.2014
comment
Это также работает для Bootstrap 4, getbootstrap.com/docs/4.0/components/scrollspy/ #параметры - person Nathan; 03.06.2020

Только с javascript это работает так же просто:

$( document ).ready(function() {
    //Scrollspy offset
    $("body").scrollspy({target: "#scroll-nav", offset:200});
});
person Turbojohan    schedule 09.03.2015

Есть более простой способ сделать это, используя атрибуты тега HTML, за которым вы хотите шпионить.

<ul class="nav nav-list affix" data-spy="affix" data-offset-top="585" data-offset-  bottom="425" id="prepare-navigation">
  <li class="nav-header">Where?</li>
  <li class="divider"></li>
  <li><a href="#at-the-museum-day-time">When?</a></li>
  <li class="divider"></li>
  <li><a href="#at-the-museum-overnight">Why?</a></li>
</ul>

Атрибуты data-offset-top и data-offset-bottom можно использовать в сочетании с суммой, на которую вы хотите компенсировать. Намного легче!

Проверьте эту ссылку для лучшего объяснения: https://stackoverflow.com/a/18326668/335567

person Deano    schedule 07.11.2013

Небольшая коррекция кода для начальной загрузки 3 (есть небольшая ошибка, когда не свернутая версия меню щелкается /некоторое мерцание/)

$('.navbar li a').click(function (event) {
var scrollPos = $('body > .container').find($(this).attr('href')).offset().top - (offsetHeight - 1);
$('body,html').animate({
    scrollTop: scrollPos
}, 500, function () {
    if ($("div.navbar-collapse").hasClass("in")) {
        $(".navbar-toggle").click();
    } else {

    }
});
return false;});
person AKIRA    schedule 10.12.2013

В CSS атрибут position тега body должен иметь значение relative.

person Zahid Hossain    schedule 10.05.2017