首页 > 解决方案 > 如何在反应中创建动画平滑的粘性标题

问题描述

我有一个标题,一旦用户开始向下滚动页面,我想将它变成一个粘性标题,它也应该是平滑的,而不仅仅是跳下屏幕,我不想只使用 aposition: fixed来粘贴它到屏幕顶部。这也在 nextjs 应用程序中。

const Header = () => {
  useEffect(() => {
    window.onscroll = () => {
      document.getElementById('header').classList.add('sticky')

      // what else do I need here
    }
  }, [])
}

...

#header {
  transition: top 1s;
}

#header.sticky {
  position: sticky;

  // what else do I need here
}

标签: javascriptcssreactjs

解决方案


你需要做几件事。

let timeout
let scroll = 0

const Header = () => {
  useEffect(() => {
    window.onscroll = () => {
      if (timeout) {
        clearTimeout(timeout)
      }

      timeout = setTimeout(() => {
        if (scroll >= window.scrollY && window.scrollY > 10) {
          document.getElementById('header').classList.add('sticky')
        } else {
          document.getElementById('header').classList.remove('sticky')
        }

        scroll = window.scrollY
      }, 10)
    }
  }, [])
}

...

#header {
  top: -100px;
  transition: top 0.5s ease-in-out;
}

#header.sticky {
  position: sticky;
  top: 0;
}
  • 在滚动时创建一个窗口事件侦听器,如果它是像 nextjs 中的服务器端呈现的应用程序,则使用 useEffect,否则您可以离开。
  • 在滚动时分配或删除粘性类,您可以使用document.getElementById或使用标题组件上的 useRef 来执行此操作。
  • 使用超时,这样事件就不会在每次滚动时触发,而是应该在滚动停止后仅 10 毫秒触发。
  • 跟踪滚动变量,以便您可以确定用户是向上还是向下滚动,这样您就可以仅在他们向上滚动时显示标题。
  • 作为一个小技巧,您可以将初始标题位置 top 设置为 -100px,如果实际上没有任何position: absolute,position: fixedposition: sticky在标题上,这将无效。然后,当您应用粘性类时,您将顶部值更改为 0,这将产生一种效果,即当您向下滚动时,标题突然从顶部“出现”。这就是创建动画的原因。

推荐阅读