文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

当我们需要往页面增加导航菜单时,有很多问题需要考虑。例如菜单的位置、样式,以及是否支持响应式等等。又或者你想给菜单增加一些动画效果。这个时候你可能想找一个 jQuery 插件可以帮你实现所有的事情。但是不需要,其实只需要一些简单代码就可以轻松创建你自己的漂亮菜单。

在这篇文章中,我将演示如何使用 JavaScript\CSS\HTML 创建一个具有动画效果的固顶导航菜单。该菜单在页面向下滚动时候显示,并在页面回到顶部时候恢复原先的样子。这是一些热门网站的普遍做法,如 Medium 和 Hacker Noon.

第 1 段(可获 1.93 积分)

阅读完上述内容后,你应该可以在你自己的设计中使用这项技术,希望能带来很好的效果。我在文章的后面提供了一些 演示程序 。

固顶导航菜单:基本 HTML 结构

下面代码是菜单骨架的 HTML 代码,这里没什么新奇的东西。

<div class="container">
  <div class="banner-wrapper">
    <div class="banner">
      <div class="top">
        <!-- Navbar top row-->
      </div>
      <div class="nav">
        <!-- Links for navigation-->
      </div>
    </div>
  </div>

  <div class="content">
    <!-- Awesome content here -->
  </div>
</div>
第 2 段(可获 0.7 积分)

使用一些样式

让我们给主元素增加一些样式。

主容器

我们需要移除任何继承下来的浏览器样式,并设置容器宽度为 100%。

*{
  box-sizing:border-box;
  padding: 0;
  margin: 0;
}

.container{
  width: 100%;
}

Banner 容器

这个容器用来包含导航菜单。它是固顶的,页面垂直滚动时隐藏并展示导航菜单。我们给它设定一个 z-index 属性来确保元素显示在内容顶部。

.banner-wrapper {
  z-index: 4;
  transition: all 300ms ease-in-out;
  position: fixed;
  width: 100%;
}
第 3 段(可获 0.98 积分)

Banner 部分

这个部分包含了导航菜单,当页面上下滚动时位置和背景颜色的变化通过 CSS 的 transition 属性进行处理。

.banner {
  height: 77px;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  background: rgba(162, 197, 35, 1);
  transition: all 300ms ease-in-out;
}

Content 部分

这部分包含一个背景图和文本,我们讲给它增加一个视差效果,文章的后面会提及。

.content {
  background: url(https://unsplash.it/1400/1400?image=699) center no-repeat;
  background-size: cover;
  padding-top: 100%;
}
第 4 段(可获 0.71 积分)

菜单动画

首先我们需要做的是给页面滚动事件一个处理函数,这样我们可以根据用户的滚动来决定显示或者隐藏菜单。我们将把所有内容附在一个 IIFE 中来避免相同页面的其他代码冲突。

(() => {
  'use strict';

  const handler = () => {
    //DOM manipulation code here
  };

  window.addEventListener('scroll', handler, false);
})();

设置初始值

我们将使用一个 refOffset 变量来代表用户往下滚动页面的量。这个值在页面刚加载完毕时为 0。然后使用一个 bannerHeight 变量来存储菜单高度,而且将需要两个对 .banner-wrapper 和 .banner DOM 元素的引用。

let refOffset = 0;
let visible = true;
const bannerHeight = 77;

const bannerWrapper = document.querySelector('.banner-wrapper');
const banner = document.querySelector('.banner');
第 5 段(可获 1.33 积分)

设置滚动方向

接下来需要设置滚动方向,并根据这个来决定是显示或者隐藏菜单。

我们将使用一个名为 newOffset 的变量。在页面加载完成该变量的值为 window.scrollY — 代表文档在当前垂直方向的滚动像素值(初始为 0)。当用户滚动页面时, newOffset 根据滚动的方向增加或者减小。如果其值大于 bannerHeight  的值则我们知道菜单已经超出了当前可见视图。

const newOffset = window.scrollY;

if (newOffset > bannerHeight) {
  // Menu out of view
} else {
  // Menu in view
}
第 6 段(可获 1.04 积分)

往下滚动将会让 newOffset 的值比 refOffset 大,这时候导航菜单应该收起并消失。往上滚动会让 newOffset 值小于 refOffset ,这时导航菜单应该重新显示。在执行完这个比较之后,我们需要更新 refOffset ,让其值等于 newOffset 以保持对用户滚动位置的跟踪。

if (newOffset > bannerHeight) {
  // Menu out of view
  if(newOffset > refOffset) {
    // Hide the menu
  } else if (newOffset < refOffset) {
    // Slide menu back down
  }

  refOffset = newOffset;
} else {
  // Menu in view
}
第 7 段(可获 0.71 积分)

菜单动画

最后我们添加两个方法:animateIn 和 an animateOut 用来显示和隐藏菜单。首先应该确认当页面到达顶部时移除菜单的透明效果:

if (newOffset > bannerHeight) {
  if (newOffset > refOffset) {
    animateOut();
  } else {
    animateIn();
  }

  refOffset = newOffset;
} else {
  banner.style.backgroundColor = 'rgba(162, 197, 35, 1)';
}

下面方法用来增加动画效果:

function animateOut() {
  bannerWrapper.style.transform = `translateY(-${bannerHeight}px)`;
  bannerWrapper.style.msTransform = `translateY(-${bannerHeight}px)`;
  bannerWrapper.style.webkitTransform = `translateY(-${bannerHeight}px)`;
  bannerWrapper.style.MozTransform = `translateY(-${bannerHeight}px)`;
  banner.style.background = 'rgba(162, 197, 35, 0.6)';
}

function animateIn() {
  bannerWrapper.style.transform = 'translateY(0px)';
  bannerWrapper.style.msTransform = 'translateY(0px)';
  bannerWrapper.style.webkitTransform = 'translateY(0px)';
  bannerWrapper.style.MozTransform = 'translateY(0px)';
  banner.style.background = 'rgba(162, 197, 35, 0.6)';
}

你可能会考虑使用一个 CSS 类来实现,并根据需要移除或者添加样式。在这种情况下我建议使用 JavaScript 实现。

第 8 段(可获 0.95 积分)

演示

这里有一个可用的菜单演示。

详情请看 ZKJVdw 发表在 CodePen 的代码。

结论

这篇文章描述了你如何使用数行代码(只需 JavaScript、CSS 和 HTML,无需 jQuery)设计一个带动画效果的导航菜单。该菜单在页面向下滚动时候显示并在向上滚动到顶时候隐藏,并实现了透明的动画效果。通过监控垂直滚动方向并应用 CSS  变换到 DOM 元素中实现。这样一个定制的解决方案给你更多的自由,编码很简单,而且设计非常灵活。

第 9 段(可获 1.33 积分)

文章评论