第22车厢-模仿大赛—仿IT邦帮忙:Sticky Nav应用篇

本篇介绍固定navBar应用篇—仿IT邦帮忙

每进入iT邦帮忙网站,忍不住都会滑一下卷轴吧?上方header算是常见的网页效果,
所以今天要来模仿一下,iT邦帮忙是怎麽做的!

▼完成图如下

结构会与IT邦帮忙的header有点不同,是以比较易懂的HTML去撰写

HTML

  <header>
    <h1><a href="/"><img
             src="https://ithelp.ithome.com.tw/storage/image/logo.svg"
             alt="iT邦帮忙"></a></h1>
  </header>
  <nav>
    <h1><a href="/"><img
             src="https://ithelp.ithome.com.tw/storage/image/nav_logo.svg"
             alt="iT邦帮忙"></a></h1>

    <ul class="menu__left">
      <li><a href="###">nav1</a></li>
      <li><a href="###">nav2</a></li>
      <li><a href="###">nav3</a></li>
      <li><a href="###">nav4</a></li>
    </ul>
  </nav>

  <div class="container">
      ...其他假文字
  </div>

CSS

  <style>
    * {
      margin: 0;
      padding: 0;
      list-style: none;
    }

    a {
      text-decoration: none;
    }

    .container {
      padding: 10px;
    }

    nav {
      background-color: #00A0E9;
      display: flex;
      padding: 0 15px;
      align-items: center;
    }

    nav .menu__left {
      display: flex;
      background-color: #00a0e9;
      transform: translateX(-120px);
      transition: 0.2s linear;
    }

    nav a {
      color: #fff;
      padding: 10px;
      display: block;
    }

    .menu--fixed {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      z-index: 100;
    }

    .menu--fixed .menu__left {
      transform: translateX(0);
    }
  </style>

逻辑

当卷轴拉到header的高度一样高时,就将nav新增class,这个class是做fixed,这时候nav就会固定,但是因为此时nav会是漂浮的状态,所以要再将nav的高度加回来

JS

 <script>
    window.addEventListener('scroll', function (e) {
      const header = document.querySelector("header");
      const nav = document.querySelector("nav");
      const scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop; 
      let topHeader = header.offsetHeight;

      console.log(scrollTop, topHeader)

      if (scrollTop >= topHeader) {
        console.log("比较高")
        nav.classList.add('menu--fixed');
        document.body.style.paddingTop = nav.offsetHeight + "px";
      } else {
        nav.classList.remove('menu--fixed');
        document.body.style.paddingTop = "0px";
      }

    }
    );

  </script>

JQ

 <script>

    $(window).scroll(function () {
      var win_h = $(document).scrollTop();

      if (win_h >= $('.header').height()) {
        $('nav').addClass('menu--fixed');
        $('body').css("padding-top", $('nav').height() + "px")
      } else {
        $('nav').removeClass('menu--fixed');
        $('body').css("padding-top", "0px")

      }
    }).scroll();
  </script>

方法介绍

JS方法 代表
window.scrollY 卷轴现在高度Y值(高度)
offsetWidth 取得元素的宽度(包含 padding 和 border)
offsetHeight 取得元素的高度(包含 padding 和 border)
offsetTop 取得相对於上层的Y座标(相对於父层的位置)
JQ方法 代表
$(window).scrollTop() 卷轴现在Y值(高度)
height() 设置或取得元素的高度
width() 设置或取得元素的宽度
innerWidth() 取得元素的宽度(含 padding)
innerHeight() 取得元素的高度(含 padding)
outerWidth() 取得元素的宽度(包含 padding 和 border)
outerHeight() 取得元素的高度(包含 padding 和 border)

范例补充

我发现小心机的logo的地方原来是这样做的
logo一直都在只是透过移动+盖背景色被隐藏了
https://ithelp.ithome.com.tw/upload/images/20211007/20142016N8Bv3pjNaK.jpg

https://ithelp.ithome.com.tw/upload/images/20211007/20142016tRv1KszjYo.jpg
等到nav 被新增了('menu--fixed') 就会套用到
.menu--fixed .menu__left { transform: translateX(0); }

当然你不透过JS,把整段JS删了,也可以只靠CSS position: sticky; 就达到同样滑到nav时固定(撇除固定时还要将Logo出现),但是因为position: sticky;IE上是没有作用的,所以还是只能透过JS达到罗!

▼ 加sticky;版本

CSS

  <style>
    * {
      margin: 0;
      padding: 0;
      list-style: none;
    }

    a {
      text-decoration: none;
    }

    .container {
      padding: 10px;
    }

    nav {
      background-color: #00A0E9;
      display: flex;
      padding: 0 15px;
      align-items: center;
      position: sticky; //增加
      top: 0;
    }

    nav .menu__left {
      display: flex;
      background-color: #00a0e9;
      transform: translateX(-120px);
      transition: 0.2s linear;
    }

    nav a {
      color: #fff;
      padding: 10px;
      display: block;
    }
  </style>

本篇参考:
https://ithelp.ithome.com.tw/articles/10249456
https://icguanyu.github.io/jquery/getsize/
https://codertw.com/%E5%89%8D%E7%AB%AF%E9%96%8B%E7%99%BC/288188/


<<:  Day22 - 用 canvas 做 圈圈叉叉游戏

>>:  Day 22 中场休息,来做点酷东西(终於要完成了)

Day 21-Unit Test 应用於 Web APIs (情境及应用-1)

Unit Test 应用於 Web APIs-前言 现今大多数的软件工程都是以网路工程为主,那网路工...

成为工具人应有的工具包-23 FileTypesMan

FileTypesMan 今天来认识这过看名字我也不清楚是啥的小工具,判断档案类型ㄉㄇ? FileT...

Day1-JavaScript(JS)与TypeScript(TS)的基本观念

Hi~开赛第一天先来简单了解一下JavaScript(JS)与TypeScript(TS)的基本观念...

Day.13 「初步学习 Javascript 基础篇」 —— Javascript 宣告变数 与 基本型别

前面已经大略介绍了 HTML 和 CSS 的入门知识了,接着我们要来认识 Javascript,来...

Day-27 特集:测试驱动开发 TDD

所谓测试驱动开发(Test-driven development, TDD),即「先写测试再开发」,...