How to hide nav when scroll down and show nav when scroll up? (要怎麽实现当滚轮往下隐藏nav,往上时显示nav?)

前言:
Hi 大家好,我是Steven,今天想用react实作一个特别的nav实现方式(因为第一次做,所以说特别XD),我记得Youtuber好像有用这种nav呈现方式,那这种特别的nav就是当我滚轮往下移动,会隐藏nav,但是往上移动时会显示nav,那话不多说,我们就开始吧!

实现:

我们先把nav切出来,这边我不会切一个漂亮的nav bar,重点是了解nav bar做动的理由。

初始状态:记得把nav的css部分设定position:fixed,这样才能跟着网页卷动来移动nav
目标:
https://ithelp.ithome.com.tw/upload/images/20210503/20126057TAlloEbjHV.jpg

当我滚轮往下移:(nav bar消失)
https://ithelp.ithome.com.tw/upload/images/20210503/20126057vlsZkOAeNa.jpg

当我稍微往上移一点:(nav bar又浮现出来)
https://ithelp.ithome.com.tw/upload/images/20210503/20126057wZ9y3QD3LQ.jpg

在react控制dom的话,最好使用 Imperative Programming的方式来操作(跟js去抓dom元素的方法不一样),所以我们先来设定控制navbar style的内容,在react中用state来控制dom元素的style呈现方式是最方便的。

设定nav的移动程度预设为0
const [moveNav, setMoveNav] = useState(0);

接下来把它插入dom元素的style
<nav style={{top:${moveNav}px}} className='move-nav'>Test Nav</nav>
这样一来,这个nav的top就会根据moveNav这个state的数值为多少来变更及渲染出正确的位置

设定好state,那我们来看看要如何控制moveNav 的数值比较恰当,因为要根据滚动页面来呈现是否显示nav,那势必跟监听scroll有很大的关西,所以我们先来设定监听函式吧!

我们把监听函式放在useEffect中(有关useEffect的使用方式这边不会详细解说,也许你可以看看其他文章,网路上很多或之後我在写篇文章分享!)。

这边设定好scroll监听函式要记得在执行下一个生命周期时移除这个scroll 监听函式(useEffect里的return部分),为了不占用记忆体空间。这边scroll是监听handleScroll这个函式,所以接下来看看怎麽编写handleScroll内容。

useEffect(()=>{
    window.addEventListener('scroll', handleScroll);

    return ()=>
    window.removeEventListener('scroll', handleScroll)
  },[])

这边我把useEffect内容全部摆上来再一一解说

useEffect(()=>{
    *在函式外先定义一个变数用来存放最後一次滚动的scrollTop为多少,这是用来跟新旧scrollTop做比较用的。*
    
    var lastScrollTop = 0;
    
    const handleScroll = () => {
      
      *这边的每次滚动,scrollTop是跟上一次滚动的lastScrollTop作比较*
      *scrollTop这麽设定是为了确保有值,你会发现window.pageYOffset和*
      *document.documentElement.scrollTop 值是一样的*
      *window.pageYOffset是离视窗顶部距离,
      *document.documentElement.scrollTop是根据html标签滚轮 目前所在位置*
      
      var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
      
      
      
      *程序由上往下读,这边是当新的scrollTop 大於 旧的scrollTop时,表示网页往下滚动,对吧?*
      *因此应该是要收起nav bar才对,所以给赋值moveNav -80这个值。*
      
      if(scrollTop > lastScrollTop){
        setMoveNav(-80)
      }
      
      *这边是相反情况,如果新的scrollTop 小於 旧的scrollTop时,表示网页网上滚动,便会显示nav bar*
      else{
        setMoveNav(0)
      }
      
      最後这边是设定每次滚动後的scrollTop,也就是所谓的旧的scrollTop,为了跟下次滚动时的新的scrollTop
      做比较而定义
      
      lastScrollTop = scrollTop;
 
    }
    window.addEventListener('scroll', handleScroll, {passive:true});


    return ()=>
    window.removeEventListener('scroll', handleScroll)
  },[])

这样以来,便能达成我要的目标,有兴趣的朋友可以复制程序码观察看看变化。

结尾:
这是我第一次写正式的技术文章,文笔和排版还不太行请大家多多包涵,也希望大家可以跟我多多交流,有错误的部分也尽请指出,那我们下一篇技术文章见啦!


<<:  危害指标(Indicators of Compromise:IoC)

>>:  2021 资通讯高峰论坛 !

[DSA] Overview: Complexity Analysis

Data Structure How to manipulate data? Data struc...

Day07 - 小记 Array.concat 与 Array.from 储存滑鼠位子

arrrayFirst.concat(arraySecond) 可以把两个 array 合并起来,直...

《Day28》Oracle Database的基础架构

Oracle Database主要由实体档案与记忆体结构配置组合而成的。 可以参考下图: 介绍Ora...

【Day 09】if ... else

前言 今天要来介绍 if 判断式,如果程序撰写到一定程度时,会需要用到一些逻辑判断,或是更复杂的表示...

AI ninja project [day 10] 基因演算法

这一篇介绍,将使用DEAP这个套件, 其实,现在比较红及使用上比较简便的套件应该是PyGAD, 但是...