根据其悬停的页面部分的背景更改固定导航栏的类 [英] Change the fixed navbar's classes depending on the background of the page section it hovers

查看:16
本文介绍了根据其悬停的页面部分的背景更改固定导航栏的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Bootstrap 4 开发一个网站,该网站的部分具有浅色和深色背景以及固定的导航栏.

导航栏是深色的(具有 css 类 bg-dark),虽然它在明亮部分很容易看到,但 与深色部分无法区分.

我尝试将导航栏的 navbar-dark bg-dark 更改为 navbar-light bg-light 当用户到达 dark 部分 (解决方案 在 StackOverflow 上被推荐):

$(window).on('activate.bs.scrollspy', function (e,obj) {if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {返回;}var isBGLight = $(obj.relatedTarget).hasClass('bg-light');$('.navbar').toggleClass('navbar-dark bg-dark', isBGLight).toggleClass('navbar-light bg-light', !isBGLight);});

.page-section {填充:70px 10px}.page-section.bg-dark * {颜色:#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 bg-dark navbar-dark fixed-top"><a class="navbar-brand" href="#">徽标</a><ul class="navbar-nav ml-auto"><li class="nav-item"><a class="nav-link" href="about.html">关于我们</a><li class="nav-item"><a class="nav-link" href="services.html">服务</a><li class="nav-item"><a class="nav-link" href="contact.html">联系方式</a></nav><div class="container-fluid bg-light page-section"><h1>第1部分</h1><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p>

<div class="container-fluid bg-dark page-section"><h1>第2部分</h1><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p>

<div class="container-fluid bg-light page-section"><h1>第3节</h1><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p>

如您所见,我使用了 scroll-spy,但打破了它的规则(它要求锚点指向具有 id 的元素"):我的导航栏的项目指向其他网站的页面,不是当前页面的部分.

适合上述情况的替代方案是什么?

解决方案

我想我会更容易正确利用 Bootstrap scrollspy 的activate.bs.scrollspy"事件,而不是打破其规则"并简单地覆盖使用 javascript 代码的默认 href 导航.

因此,我建议您将 id 添加回 div,并将匹配的 framgment href 添加到锚点,让 Bootstrap 通过 obj.relatedTarget 属性在activate.bs.scrollspy"事件中为您提供目标,切换根据需要使用类,并可选择从导航项中删除已激活"类,使其看起来不像部分相关.如果您有其他部分,请尝试使用隐藏的锚点或完全隐藏的导航.

当然,在我看来,最干净的方法是放弃滚动间谍并使用 window.scrollY 和 $(window).on('scroll', ...).

查看代码片段:

$(window).on('activate.bs.scrollspy', function (e, obj) {if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {返回;}var isBGLight = $(obj.relatedTarget).hasClass('bg-light');$('.navbar').toggleClass('navbar-dark bg-dark', isBGLight).toggleClass('navbar-light bg-light', !isBGLight);//可选:从锚点中删除活动类,使其看起来不像导航链接到部分$('.navbar-nav a[href="' + obj.relatedTarget + '"]').removeClass('active');});//这里我们做实际的导航$('.navbar-nav a').click(function(e) {//防止锚点在导航到另一个页面之前短暂跳转到给定部分的默认行为e.preventDefault();//子串消除前导#"window.location.href = $(e.target).attr('href').substring(1) + '.html';})

.page-section {填充:70px 10px}.page-section.bg-dark * {颜色:#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 bg-dark navbar-dark fixed-top"><a class="navbar-brand" href="#">徽标</a><ul class="navbar-nav ml-auto"><li class="nav-item"><!--注意我将 hrefs 更改为指向 div id--><a class="nav-link" href="#about">关于我们</a><li class="nav-item"><a class="nav-link" href="#services">服务</a><li class="nav-item"><a class="nav-link" href="#contact">联系方式</a></nav><!--注意我添加了 id 是为了让 Bootstrap 完成它的工作--><div id="about" class="container-fluid bg-light page-section"><h1>第1部分</h1><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p>

<div id="services" class="container-fluid bg-dark page-section"><h1>第2部分</h1><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p>

<div id="contact" class="container-fluid bg-light page-section"><h1>第3节</h1><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p><p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分并在滚动时查看导航栏!</p>

I am working on a website in Bootstrap 4, that has sections with light and dark backgrounds and a fixed navbar.

The navbar is dark (has the css class bg-dark) and, while it is easily visible against the light sections, it is indistinguishable against the dark ones.

I have tried to change the navbar's navbar-dark bg-dark to navbar-light bg-light when the user reaches a dark section (the solution was suggested on StackOverflow):

$(window).on('activate.bs.scrollspy', function (e,obj) {
    if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
        return;
    }
    var isBGLight = $(obj.relatedTarget).hasClass('bg-light');
    $('.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 bg-dark navbar-dark fixed-top">
    <a class="navbar-brand" href="#">Logo</a>
    <ul class="navbar-nav ml-auto">
      <li class="nav-item">
        <a class="nav-link" href="about.html">About Us</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="services.html">Services</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="contact.html">Contact</a>
      </li>
    </ul>
  </nav>

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

As you can see, I have used scroll-spy but broken its rules (which state that it requires anchors to "point to an element with an id"): my navbar's items point to other pages of the website and not to sections of the current page.

What is the alternative suited for the situation above?

解决方案

I'm thinking i'd be easier to properly exploit Bootstrap scrollspy's "activate.bs.scrollspy" event rather than "breaking its rules" and simply override the default href navigation with javascript code.

So i'd suggest you add back the id's to the divs and the matching framgment hrefs to the anchors, let Bootstrap give you the target in the "activate.bs.scrollspy" event via the obj.relatedTarget property, toggle the classes as needed and optionally remove the "activated" class from the nav items so it doesn't appear like the sections are related. If you have additional sections, try using hidden anchors or a hidden nav altogether.

Of course, the cleanest way would be in my opinion to ditch the scrollspy and use window.scrollY and $(window).on('scroll', ...).

Check out the snippet:

$(window).on('activate.bs.scrollspy', function (e, obj) {
    if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
        return;
    }

    var isBGLight = $(obj.relatedTarget).hasClass('bg-light');
    $('.navbar').toggleClass('navbar-dark bg-dark', isBGLight)
                .toggleClass('navbar-light bg-light', !isBGLight);

    //Optional: Remove the active class from the anchor so it doesn't look like the nav is linked to the sections
    $('.navbar-nav a[href="' + obj.relatedTarget + '"]').removeClass('active');
});

//Here we do the actual navigation
$('.navbar-nav a').click(function(e) {
    //Prevent anchor's default behaviour of briefly jumping to the given section before navigating to another page
    e.preventDefault();
    //Substring to eliminate the leading "#"
    window.location.href = $(e.target).attr('href').substring(1) + '.html';
})

.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 bg-dark navbar-dark fixed-top">
    <a class="navbar-brand" href="#">Logo</a>
    <ul class="navbar-nav ml-auto">
      <li class="nav-item">
        <!--Notice I changed the hrefs to point to the div ids-->
        <a class="nav-link" href="#about">About Us</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#services">Services</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#contact">Contact</a>
      </li>
    </ul>
  </nav>

  <!--Notice I added the id's to let Bootstrap do it's job-->
  <div id="about" 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="services" 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="contact" 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>

这篇关于根据其悬停的页面部分的背景更改固定导航栏的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆