Используйте scroll-spy для изменения классов фона панели навигации - PullRequest
0 голосов
/ 31 августа 2018

Я работаю над веб-страницей в Bootstrap 4, в которой есть разделы со светлым и темным фоном и фиксированная панель навигации. Навбар темный (имеет класс css bg-dark) и, хотя он легко виден на светлых участках, он не различим на темных .

Я добавил на страницу шпион прокрутки Bootstrap, но он делает только добавление класса active к элементам панели навигации, как показано ниже:

.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>

Как я могу изменить navbar-dark bg-dark панели навигации на navbar-light bg-light, когда пользователь достигает div с id section3 или (еще лучше) с class bg-light?

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

Использовать код JS для переключения класса

 $(window).on('activate.bs.scrollspy', function (e,obj) 
{
   if(document.querySelector(obj.relatedTarget).classList.contains('bg-light'))
   {
      $('.navbar').removeClass("navbar-dark bg-dark");
      $('.navbar').addClass("bg-light navbar-light" );
   }
   else
   {
      $('.navbar').removeClass("bg-light navbar-light");
      $('.navbar').addClass( "navbar-dark bg-dark" );
   }
});
.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>
0 голосов
/ 29 ноября 2018

здесь вам необходим тест, но для прокрутки на 1 px и после начала изменения для некоторых состояний. извините мой плохой английский.

https://codepen.io/jhonycertz/pen/eQPbXy

$(window).scroll(function() {

  var isScrolled = $(document).scrollTop() > 1;
    $('.menu').toggleClass('nav_white', isScrolled);
  
$(window).on('activate.bs.scrollspy', function (e,obj) {
  if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
  	return;
  }
	var Transparent = $(obj.relatedTarget).hasClass('nav_transparent');
  var White = $(obj.relatedTarget).hasClass('nav_white');
  var Blue = $(obj.relatedTarget).hasClass('nav_blue');
  $('.nav').toggleClass('nav_transparent', Transparent, !White, !Blue)
              .toggleClass('nav_white', White, !Transparent, !Blue)
              .toggleClass('nav_blue', Blue, !Transparent, !White);
});
  });
.page-section {
  padding: 70px 10px
}
.move{
  background-color:#000
}
.page-section.bg-dark * {
  color: #fff;
}
.transparent{
  background-color:green;
}
.nav_transparent{background-color:yellow;}
.nav_white{background-color:grey;}
.nav_blue{background-color:black;}
<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=".nav" data-offset="15">
  <nav class="menu nav navbar navbar-expand-sm nav_transparent fixed-top">
    <ul class="navbar-nav">
     <li class="nav-item ">
        <a class="nav-link" href="#section">Section 0</a>
      </li>
      <li class="nav-item d-none">
        <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>
       <li class="nav-item">
        <a class="nav-link" href="#section4">Section 4</a>
      </li>
    </ul>
  </nav>
  <div id="section" class="container-fluid bg-light page-section">
    <h1>Section 0</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="section1" class="container-fluid bg-light page-section nav_transparent">
    <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-light page-section nav_blue">
    <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="nav_white container-fluid bg-dark 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>
  <div id="section4" class="nav_blue container-fluid bg-light page-section">
    <h1>Section 4</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>
0 голосов
/ 31 августа 2018

Нет встроенного способа изменить цель активного класса, поэтому у вас остается опция 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/

...