Simple React Affixed Module - 简版 React 固钉

写的时候参考了非常多网络上的代码,故发出来共享,共同进步。

变量说明:

  • NavBarHeight: 按需填入
  • offset: 自行传入的修正偏移量(比如说,待固定的元素上方存在 margin-bottom)
  • switched: 用以支持存在多个界面的 component ,但需要先给你的 component 添加 this.state.switched 并传入本模块来辅助判断
  • classname & style: 略
import PropTypes from 'prop-types';
import React, { Component } from 'react';

class Affix extends Component {
  static NavBarHeight = xxx;

  constructor(props) {
    super(props);
    this.state = {
      affix: false,
    };
    this.offset = 0;
  }

  componentDidMount() {
    window.addEventListener('scroll', this.handleScroll);
    this.offset = this.refs.fixedNode.getBoundingClientRect().top - Affix.NavBarHeight - this.props.offset;
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.switched !== nextProps.switched) {
      this.setState({ affix: false });
    }
  }

  componentDidUpdate(prevProps) {
    if (this.props.switched !== prevProps.switched && !this.state.affix) {
      this.offset = this.refs.fixedNode.getBoundingClientRect().top - Affix.NavBarHeight - this.props.offset;
    }
  }

  componentWillUnmount() {
    window.removeEventListener('scroll', this.handleScroll);
  }

  handleScroll = () => {
    const affix = this.state.affix;
    const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

    if (!affix && scrollTop >= this.offset) {
      this.setState({
        affix: true,
      });
    }

    if (affix && scrollTop < this.offset) {
      this.setState({
        affix: false,
      });
    }
  };

  render() {
    const affix = this.state.affix ? 'affix' : '';
    const style = this.state.affix ? this.props.style : {};
    const { className } = this.props;

    return (
      
{this.props.children}
); } } Affix.propTypes = { className: PropTypes.string, offset: PropTypes.number, style: PropTypes.object, switched: PropTypes.bool, }; Affix.defaultProps = { className: '', offset: 0, style: {}, switched: false, }; export default Affix;

你可能感兴趣的:(Simple React Affixed Module - 简版 React 固钉)