Bootstrap 3 - ScrollSpy
В этом уроке Вы узнаете, как использовать плагин "scrollspy", отвечающий за слежением положения прокрутки, для создания навигации внутри страницы с помощью платформы Bootstrap.
Использования плагина ScrollSpy для создании навигации внутри страницы с помощью компонента Bootstrap Nav
Плагин "ScrollSpy" применяется на сайтах, веб-страницы которого содержат огромное количество материала и пользователю трудно в нём ориентироваться. В таком случае разработчик может создать разделы на каждой страницы и с помощью плагина ScrollSpy отслеживать, в каком разделе остановился посетитель. В итоге у нас получится навигационное меню (nav
), у которого будут подсвечиваться пункты по мере прокрутки страницы, тем самым подсказывая посетителю, в каком разделе он находится. Подсвечивающиеся пункты можно реализовать посредством добавления класса .active
к пунктам навигационного меню (nav
), основываясь на плагине "ScrollSpy", который будет отслеживать нахождения посетителя в том или ином разделе. Также с помощью навигационного меню можно будет переходить к соответствующим разделам страницы.
Добавить функциональность плагина "Scrollspy" в навигационное меню можно с помощью атрибутов data
или сценариев на языке JavaScript.
Использование плагина Scrollspy с помощью атрибутов data
Для начала добавьте атрибут data-spy="scroll"
к элементу, за которым вы хотите чтобы "scrollspy" наблюдал (как правило, это элемент body
). Затем добавьте атрибут data-target
с идентификатором (#id
) или классом (.class
) элемента-контейнера, который содержит навигационное меню (компонент nav
). Для этого, чтобы это меню работало, вы должны иметь в основной части страницы разделы с идентификаторами, за которыми ScrollSpy будет следить, и они должны совпадать с атрибутом href
пунктов навигационного меню, с помощью которых они ссылаются на эти разделы.
<body data-spy="scroll" data-target="#navbar-example"> ... <!-- Навигационное меню --> <div class="navbar-example"> <ul class="nav nav-tabs"> <li class="active"><a href="#section1">1 Раздел</a></li> <li><a href="#section2">2 Раздел</a></li> <li><a href="#section3">3 Раздел</a></li> </ul> </div> <!-- Контент страницы, состоящий из разделов --> <h2 id="section1">1 Раздел</h2> <p><!--Содержание раздела --></p> <h4 id="section2">2 Раздел</h4> <p><!--Содержание раздела --></p> <h4 id="section3">3 Раздел</h4> <p><!--Содержание раздела --></p> </body>
Использование плагина Scrollspy с помощью создания сценария на языке JavaScript
Вы можете вызвать "scrollspy" не только с помощью атрибутов data
, но и с помощью сценария на языке JavaScript. В сценарии необходимо задать элемент, за которым необходимо наблюдать (например: body
), а затем вызвать функцию .scrollspy()
. Функции необходимо задать параметр "target", значением которого будет идентификатор или класс контейнера, в который помещено навигационное меню.
$('body').scrollspy({ target: '.navbar-example' })
Следующий пример демонстрирует использование плагина scrollspy с помощью атрибутов data
<!-- Контент страницы --> <div data-spy="scroll" data-target="#navbar-example" data-offset="0" style="height:200px;overflow:auto; position: relative; border: 1px solid black; padding: 10px;"> <h4 id="windows">Windows</h4> <p><!--Содержание раздела --></p> <h4 id="linux">Linux</h4> <p><!--Содержание раздела --></p> <h4 id="android">Android</h4> <p><!--Содержание раздела --></p> <h4 id="ios">iOS</h4> <p><!--Содержание раздела --></p> <h4 id="wphone">Windows Phone</h4> <p><!--Содержание раздела --></p> </div> <!-- Навигационное меню --> <nav id="navbar-example" class="navbar navbar-default navbar-static" role="navigation"> <div class="navbar-header"> <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-scrollspy"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="collapse navbar-collapse navbar-scrollspy"> <!-- Пункты навигационного меню --> <ul class="nav navbar-nav"> <li><a href="#windows">Windows</a></li <li><a href="#linux">Linux</a></li> <li><a href="#android">Android</a></li> <li><a href="#ios">iOS</a></li> <li><a href="#wphone">Windows Phone</a></li> </ul> </div> </nav>

Параметр offset плагина ScrollSpy
У плагина "Scrollspy" есть один параметр offset
, который можно установить с помощью атрибута data
(например: data-offset="0"
) или с помощью JavaScript (например: $(".scroll-area").scrollspy({target: "#myNavbar", offset: 500})
). Данный параметр предназначен для задания количества пикселей от верхнего края при расчете позиции прокрутки. По умолчанию, значения данного параметра равно 10.
Метод scrollspy('refresh')
При вызове метода "scrollspy" через JavaScript Вам необходимо вызвать метод .refresh
для обновления объектной модели документа (DOM). Это полезный метод, если какие-то элементы DOM изменились, т.е. если вы добавили или удалили некоторые элементы из объектной модели документа HTML. Нижеприведенный код использует этот метод:
$('body').each(function () { var $spy = $(this).scrollspy('refresh') });Следующий пример демонстрирует использование метода
.scrollspy('refresh')
:
<!-- Контент страницы, состоящий из разделов --> <div id="mySampleText" data-spy="scroll" data-target="#myScrollspy2" data-offset="0" style="height:200px;overflow:auto; position: relative;"> <div class="section"> <h4 id="html">HTML<small><a href="#" onclick="removeSection(this);"> × Удалить эту секцию</a></small> </h4> <p>Содержимое раздела...</p> </div> <div class="section"> <h4 id="css">CSS</h4> <p>Содержимое раздела...</p> </div> <div class="section"> <h4 id="bootstrap3">Bootstrap 3<small><a href="#" onclick="removeSection(this);"> × Удалить эту секцию</a></small> </h4> <p>Содержимое раздела...</p> </div> </div> <!-- Навигационное меню --> <nav id="myScrollspy2" class="navbar navbar-default navbar-static" role="navigation"> <div class="navbar-header"> <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-scrollspy2"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="collapse navbar-collapse navbar-scrollspy2"> <ul class="nav navbar-nav"> <li class="active"><a href="#html">HTML</a></li> <li><a href="#css">CSS</a></li> <li><a href="#bootstrap3">Bootstrap 3</a></li> </ul> </div> </nav> <!-- Скрипт на языке JavaScript --> <script type="text/javascript"> $(function(){ removeSection = function(e) { $(e).parents(".section").remove(); $("#mySampleText").each(function () { var $spy = $(this).scrollspy('refresh') }); } $("#myScrollspy2").scrollspy(); }); </script>

Событие activate.bs.scrollspy плагина ScrollSpy
Плагин Bootstrap scrollspy включает в себя событие activate.bs.scrollspy
, которое предназначено для перехвата состояния плагина scrollspy. Это событие срабатывает каждый раз, когда новый элемент активируется с помощью плагина scrollspy, который эти элементы отслеживает. Например: $('#myScrollspy').on('activate.bs.scrollspy', function () {
// do something… })
Следующий пример демонстрирует использование события activate.bs.scrollspy
:
<body data-spy="scroll" data-target="#myScrollspy"> <!-- Навигационное меню --> <nav id="myScrollspy" class="navbar navbar-default navbar-static" role="navigation"> <div class="navbar-header"> <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-scrollspy"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="collapse navbar-collapse navbar-scrollspy"> <ul class="nav navbar-nav"> <li class="active"><a href="#computer">Компьютер</a></li> <li><a href="#laptop">Ноутбук</a></li> <li><a href="#tablet">Планшет</a></li> </ul> </div> </nav> <!-- Основное содержимое --> <div data-spy="scroll" data-target="#myScrollspy" data-offset="0" style="height:200px;overflow:auto; position: relative;"> <div class="section"> <h4 id="computer">Компьютер<small><a href="#" onclick="removeSection(this);"> × Удалить эту секцию</a></small> </h4> <p>Содержимое секции...</p> </div> <div class="section"> <h4 id="laptop">Ноутбук<small></small></h4> <p>Содержимое секции...</p> </div> <div class="section"> <h4 id="tablet">Планшет<small><a href="#" onclick="removeSection(this);"> × Удалить эту секцию</a></small> </h4> <p>Содержимое секции...</p> </div> </div> <!-- Сценарий на языке JavaScript --> <script type="text/javascript"> $(function(){ removeSection = function(e) { $(e).parents(".section").remove(); $('[data-spy="scroll"]').each(function () { var $spy = $(this).scrollspy('refresh') }); } $("#myScrollspy").scrollspy(); $('#myScrollspy').on('activate.bs.scrollspy', function () { var currentItem = $(".nav li.active > a").text(); alert("Сейчас вы находитесь - " + currentItem); }) }); </script> </body>

Если запустить исходный код в браузере, то history в навигации работает или мне кажется. Нужно так же но чтобы компоненты лежали не в <body а в <div class=«scroll-area1»…
Есть ли техничное стандартное решение? Велосипед сделать не проблема
Его содержимое должно выполнять следующее:
1. Как-то узнать, что изменения hash страницы связано с переходом по кнопки «Назад» или «Вперёд». Если это не связано с кликом по одной из кнопок, то прервать выполнение функции.
2. Определить положения родительского элемента и соответственно позицию прокручиваемого элемента внутри него.
3. Прокрутить страницу и содержимое прокручиваемого элемента до цели.
Я так понял он закреплен в class=«nav» при прокрутке разделы подсвечиваются, у меня иная задача отключить подсветку разделов при прокрутке, но оставить при наведении. Каким образом можно реализовать?
В этом случае не используйте ScrollSpy.
Николай, если это возможно на сайте, то установите одинаковые значения top, тогда скачка не будет. Или хотя уменьшите эту разницу насколько возможно, тогда этот скачок будет меньше.
Но если это не возможно, тогда можно только сгладить этот эффект с помощью анимации. Например, если у вас элемент в static имеет «top: 80px», а в fixed имеет «top: 100px», то эти 20px ни куда не денешь. И у вас возникает резкий переход в 20px видимый глазу. Например, анимацию можно сделать с помощью jquery.scrollTo или чего-нибудь другого.