【问题标题】:React - Slide fixed navbar up on scroll down and slide down on scroll upReact - 向下滚动时向上滑动固定导航栏,向上滚动时向下滑动
【发布时间】: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.

【问题讨论】:

    标签: javascript html css reactjs jsx


    【解决方案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在哪里
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    • 1970-01-01
    相关资源
    最近更新 更多