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 (
      <div
        className={`${className || ''} ${affix}`}
        style={style}
        ref={'fixedNode'}
      >
        {this.props.children}
      </div>
    );
  }
}

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;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,814评论 1 92
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,991评论 19 139
  • 做React需要会什么? react的功能其实很单一,主要负责渲染的功能,现有的框架,比如angular是一个大而...
    苍都阅读 14,818评论 1 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,540评论 25 708
  • 家中有几个小音响一直吃灰,于是想到连到树莓派上,用手机控制,来个无线播放,媲美蓝牙音响了。 原理是通过DLNA协议...
    静夜思_阅读 2,418评论 3 3