React - 向下滚动时向上滑动固定导航栏,向上滚动时向下滑动

Posted

技术标签:

【中文标题】React - 向下滚动时向上滑动固定导航栏,向上滚动时向下滑动【英文标题】:React - Slide fixed navbar up on scroll down and slide down on scroll up 【发布时间】:2018-05-06 13:50:30 【问题描述】:

tl;dr 向下滚动查看适合我的解决方案!

如何在react中实现固定导航栏上下滑动?

使用 refs 或使用 componentDidMount 生命周期挂钩的更好方法是什么?

  hideNav = (navbar) => 
    const hide = () => 
      let lastScrollTop = 0;
      const currentScrollTop = navbar.scrollTop;

      // scroll down
      if (currentScrollTop > lastScrollTop) 
      navbar.classList.add('hidden');
       else 
      // scroll up
        navbar.classList.remove('hidden');
      
      lastScrollTop = currentScrollTop;
    ;

    window.addEventListener('scroll', hide);
  ;

...在渲染方法中进一步向下:

 render() 
      return <Navbar ref=this.hideNav />

更新:

解决方案:

class Navbar extends React.Component 
  state = 
    auth: false,
    slide: 0,  // How much should the Navbar slide up or down
    lastScrollY: 0,  // Keep track of current position in state
  ;

  componentWillMount() 
    // When this component mounts, begin listening for scroll changes
    window.addEventListener('scroll', this.handleScroll);
  

  componentWillUnmount() 
    // If this component is unmounted, stop listening
    window.removeEventListener('scroll', this.handleScroll);
  

  handleScroll = () => 
    const  lastScrollY  = this.state; 
    const currentScrollY = window.scrollY;


    if (currentScrollY > lastScrollY) 
      this.setState( slide: '-48px' );
     else 
      this.setState( slide: '0px' );
    
    this.setState( lastScrollY: currentScrollY );
  ;

   render()     
    return (
      <Navbar
        style=
          transform: `translate(0, $this.state.slide)`,
          transition: 'transform 90ms linear',
        
      />
     );
   
 

我还没有进行任何优化,因此建议使用 requestAnimationFrame、setTimeout 或 customEvent 来限制事件。 Like here.

【问题讨论】:

【参考方案1】:

您不应将 refs 用作注册事件侦听器或添加/删除类的解决方案。正如您所建议的,您应该使用组件生命周期挂钩来开始(和停止)侦听窗口上的滚动。

export default class App extends Component 
  state =  hidden: false ;

  constructor(props) 
    super(props);

    // Bind the function to this component, so it has access to this.state
    this.handleScroll = this.handleScroll.bind(this);
  

  componentWillMount() 
    // When this component mounts, begin listening for scroll changes
    window.addEventListener('scroll', this.handleScroll);
  

  componentWillUnmount() 
    // If this component is unmounted, stop listening
    window.removeEventListener('scroll', this.handleScroll);
  

  handleScroll(e) 
    let lastScrollTop = 0;
    const currentScrollTop = navbar.scrollTop;

    // Set the state of hidden depending on scroll position
    // We only change the state if it needs to be changed
    if (!this.state.hidden && currentScrollTop > lastScrollTop) 
      this.setState( hidden: true );
     else if(this.state.hidden) 
      this.setState( hidden: false );
    
    lastScrollTop = currentScrollTop;
  

  render() 
    // We pass a hidden prop to Navbar which can render className="hidden" if the prop is true
    return (
      <Navbar hidden=this.state.hidden />
    );
  

另外,查看您提供的滚动功能,它不会起作用,因为lastScrollTop 将始终为 0。如果您正在寻找滚动解决方案,请查看此答案,因为它具有类似的解决方案您的固定导航栏需要什么(除了隐藏而不是显示):Sticky Header after scrolling down

【讨论】:

感谢您的解决方案。不幸的是,我无法按照您的描述让它为我工作,但我想出了一种方法来处理组件状态下的所有内容,因此我不必将任何道具传递给组件。我发布了更新。 这个解决方案太棒了!!这让我也避免使用querySelector()style 请问来自@const currentScrollTop = navbar.scrollTop的navbar com在哪里

以上是关于React - 向下滚动时向上滑动固定导航栏,向上滚动时向下滑动的主要内容,如果未能解决你的问题,请参考以下文章

底部应用栏在使用片段导航时向上/向下滑动(导航架构组件)

粘性侧边栏:向下滚动时固定在底部,向上滚动时固定在顶部

为啥我的导航栏在向下滚动时不隐藏而在向上滚动时出现?

向下滚动时隐藏导航栏并在用户使用 jquery 向上滚动页面时显示它,不能正常工作

双向滚动时隐藏固定菜单

在 Flutter 中的 Scroll 上隐藏底部导航栏