向下滚动时导航栏发生变化,如何使变化响应?

Navbar change when scrolling down, how to make the change responsive?

我正在创建一个基本网页,我在其中制作了一个非常基本的透明导航栏,其中白色 fontor 字体与深色背景横幅重叠。向下滚动并达到浅色背景时,字体会变成黑色(至少这是目标)。

事实是,更改不是响应式的,这意味着根据设备和屏幕大小,导航栏更改不会恰好发生在横幅的底部。有没有办法做到这一点?这是我的代码:

1/HTML

家 技能 文件夹 生物 恢复 接触

<div class="banner">
  <div class="background-gradient">
    <video autoplay muted loop id="myVideo">
      <source src="images/Background_Loop_small.mp4" type="video/mp4">
    </video>
  </div>

  <div class="content">
    <div class="presentation">
      <img src="images/avatar2.jpg" id="avatar">
      <h1 id="place-title">Olivier Girardot</h1>
      <h3 id="text-white">Junior Full-Stack Web Developper</h3>

      <section id="section01" class="demo">
        <div class="container" style="height: 80px"></div>
        <a href="#section02"><span></span><span></span><span></span></a>
      </section>
    </div>
  </div>
</div>

2/CSS

.navbar {
  margin: 0;
  background: transparent;
  position: fixed;
  color: white;
  display: flex;
  height: 60px;
  z-index: 10;
}

.navbar-links {
  display: flex;
  align-items: center;
  padding: 0px 10px;
}

.navbar-links a:hover {
  opacity: 0.7;
}

.menu {
  position: relative;
  display: flex;
  align-items: center;
  right: 0;
}

.menu a {
  color: white;
  text-decoration: none;
  font-size: 1vw;
  font-weight: 500;
  padding: 0px 10px;
}

.menu a:hover {
  border-bottom: solid white 1px;
}

.navbar-under {
    margin: 0;
    background: #f0f0f0;
    position: fixed;
    color: black;
    display: flex;
    height: 30px;
    z-index: 10;
}

.menu-under {
  position: relative;
  display: flex;
  align-items: center;
  right: 0;
}

.menu-under a {
  color: black;
  text-decoration: none;
  font-size: 1vw;
  font-weight: 500;
  padding: 0px 10px;
}

.menu-under a:hover {
  border-bottom: solid black 1px;
}

3/Javascript

const navbar = document.querySelector(".navbar");
const menu = document.querySelector(".menu");

window.addEventListener('scroll', () => {
  if (window.scrollY > 700) {
    navbar.classList.remove('navbar');
    navbar.classList.add("navbar-under");
  }
});

window.addEventListener('scroll', () => {
  if (window.scrollY < 700) {
    navbar.classList.remove("navbar-under");
    navbar.classList.add('navbar');
  }
});

window.addEventListener('scroll', () => {
  if (window.scrollY > 700) {
    menu.classList.remove('menu');
    menu.classList.add("menu-under");
  }
});

window.addEventListener('scroll', () => {
  if (window.scrollY < 700) {
    menu.classList.remove("menu-under");
    menu.classList.add('menu');
  }
});

所以我猜问题出在 window.scrollY > 700window.scrollY < 700,有没有办法让它具有响应性,并使导航栏恰好在横幅底部发生变化?

与其监听滚动事件,不如看看 Intersection Observer (IO)

有了这个,您可以在元素与另一个元素或视口重叠时做出反应,因此您可以将其用于导航栏。

这是一个简单的例子,说明它是如何工作的。它并不完美,但它应该为您充实它提供一个良好的起点。

如果您需要支持 IE 等旧版浏览器,请查看 official polyfill from w3c

const sections = document.querySelectorAll('div');
const config = {
  rootMargin: '0px',
  threshold: [.2, .9]
};

const observer = new IntersectionObserver(function (entries, self) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      var headerEl = document.querySelector('header');
      if (entry.intersectionRatio > 0.9) {
        //intersection ratio bigger than 90%
        //-> set header according to target
        headerEl.className=entry.target.dataset.header;      
      } else {
        //-> check if element is coming from top or from bottom into view
        if (entry.target.getBoundingClientRect().top < 0 ) {
          headerEl.className=entry.target.dataset.header;
        }
      } 
    }
  });
}, config);

sections.forEach(section => {
  observer.observe(section);
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.g-100vh {
height: 100vh
}

header {
  min-height: 50px;
  position: fixed;
  background-color: green;
  width: 100%;
}
  
header.white-menu {
  color: white;
  background-color: black;
}

header.black-menu {
  color: black;
  background-color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<header>
 <p>Header Content </p>
</header>
<div class="grid-30-span g-100vh white-menu" style="background-color:darkblue;" data-header="white-menu">
    
</div>

<div class="grid-30-span g-100vh black-menu" style="background-color:lightgrey;" data-header="black-menu">
    
</div>

<div class="grid-30-span g-100vh white-menu" style="background-color:darkblue;" data-header="white-menu">
    
</div>