Нет встроенного способа изменить цель активного класса, поэтому у вас остается опция javascript. К счастью, Bootstrap 4 предоставляет событие, которое срабатывает при установке нового активного элемента. Одна странность в том, что документация предполагает, что вы можете добавить событие слушателя к элементу с data-spy
. Это не работает. Вы должны добавить его к объекту window
(https://stackoverflow.com/a/48694139/854246). Вот фрагмент кода:
$(window).on('activate.bs.scrollspy', function (e,obj) {
// spy changes to the last item at the end of the page,
// so we want to avoid changing the class at this point.
// Spy still works, but we want the class to be based on
// whatever block was closest.
// https://stackoverflow.com/a/40370876/854246
if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
return;
}
// Here we detect the targets class. I'm just using bg-
// light. Not the most robust solution, but it can be
// tweaked.
var isBGLight = $(obj.relatedTarget).hasClass('bg-light');
// note that navbar needs two classes to work. If you
// only set bg-light/bg-dark, the link text color doesn't
// change.
$('.navbar').toggleClass('navbar-dark bg-dark', isBGLight)
.toggleClass('navbar-light bg-light', !isBGLight);
});
.page-section {
padding: 70px 10px
}
.page-section.bg-dark * {
color: #fff;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<body data-spy="scroll" data-target=".navbar" data-offset="15">
<nav class="navbar navbar-expand-sm navbar-dark bg-dark fixed-top">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="#section1">Section 1</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#section2">Section 2</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#section3">Section 3</a>
</li>
</ul>
</nav>
<div id="section1" class="container-fluid bg-light page-section">
<h1>Section 1</h1>
<p>Try to scroll this section and look at the navigation bar while scrolling! Try to scroll this section and look at the navigation bar while scrolling!</p>
<p>Try to scroll this section and look at the navigation bar while scrolling! Try to scroll this section and look at the navigation bar while scrolling!</p>
</div>
<div id="section2" class="container-fluid bg-dark page-section">
<h1>Section 2</h1>
<p>Try to scroll this section and look at the navigation bar while scrolling! Try to scroll this section and look at the navigation bar while scrolling!</p>
<p>Try to scroll this section and look at the navigation bar while scrolling! Try to scroll this section and look at the navigation bar while scrolling!</p>
</div>
<div id="section3" class="container-fluid bg-light page-section">
<h1>Section 3</h1>
<p>Try to scroll this section and look at the navigation bar while scrolling! Try to scroll this section and look at the navigation bar while scrolling!</p>
<p>Try to scroll this section and look at the navigation bar while scrolling! Try to scroll this section and look at the navigation bar while scrolling!</p>
</div>
</body>
Я хотел бы сделать это фрагментом стека, но переполнению стека не нравится, когда вы слушаете события на объекте window
по соображениям безопасности (изолированное окно iframe и еще много чего), так что вот скрипка, демонстрирующая это Решение: По-видимому, оно поддерживает его. Просто не нравится, когда вы используете console.log
https://jsfiddle.net/jmarikle/jzg7ok0v/