繁体   English   中英

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

[英]React - Slide fixed navbar up on scroll down and slide down on scroll up

tl; dr 向下滚动以获取对我有用的解决方案!

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

使用 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 来限制事件。 就像这里。

您不应该使用 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。如果您正在寻找滚动解决方案,请查看此答案,因为它具有与固定导航栏类似的解决方案需要(除了,隐藏而不是显示): 向下滚动后的粘性标题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM