Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save matchatype/fa27926e507397f23014d9936a5a848f to your computer and use it in GitHub Desktop.

Select an option

Save matchatype/fa27926e507397f23014d9936a5a848f to your computer and use it in GitHub Desktop.

Revisions

  1. @brthornbury brthornbury created this gist Feb 3, 2017.
    138 changes: 138 additions & 0 deletions reactsjs-scroll-in-nav.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,138 @@
    Ensure you have `raf` installed: `npm install --save raf`

    This is the code for the component.

    ```jsx
    import raf from 'raf';

    export default class ScrollInNav extends Component {
    static propTypes = {
    scrollInHeight: React.PropTypes.number
    };

    static defaultProps = {
    scrollInHeight: 50
    };

    fixedStyle = {
    position: 'fixed',
    WebkitTransition: 'all .2s ease-in-out',
    MozTransition: 'all .2s ease-in-out',
    OTransition: 'all .2s ease-in-out',
    transition: 'all .2s ease-in-out',
    top: 0,
    left: 0,
    right: 0,
    zIndex: 1
    };

    hiddenStyle = {
    WebkitTransform: 'translateY(-100%)',
    MsTransform: 'translateY(-100%)',
    transform: 'translateY(-100%)'
    };

    scrolledInStyle = {
    WebkitTransform: 'translateY(0)',
    MsTransform: 'translateY(0)',
    transform: 'translateY(0)'
    };

    constructor(props) {
    super(props);

    this.state = {
    hidden: true
    };

    this.handlingScrollUpdate = false;
    }

    getScrollY = () => {
    if (window.pageYOffset !== undefined) {
    return window.pageYOffset
    } else if (window.scrollTop !== undefined) {
    return window.scrollTop
    } else {
    return (document.documentElement || document.body.parentNode || document.body).scrollTop
    }
    }

    handleScroll = () => {
    if (!this.handlingScrollUpdate) {
    this.handlingScrollUpdate = true;
    raf(this.update);
    }
    }

    update = () => {
    let currentScrollY = this.getScrollY();
    console.log(currentScrollY);
    console.log(this.props.scrollInHeight);

    this.setState({
    hidden: currentScrollY < this.props.scrollInHeight
    });

    this.handlingScrollUpdate = false;
    }

    componentDidMount() {
    window.addEventListener('scroll', this.handleScroll);
    }

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

    render() {
    let renderStyle = this.fixedStyle;
    renderStyle = this.state.hidden ?
    {...renderStyle, ...this.hiddenStyle} :
    {...renderStyle, ...this.scrolledInStyle};

    return (
    <div className="scroll-in-nav" ref="scrollnav" style={renderStyle}>
    {this.props.children}
    </div>
    );
    }
    }
    ```

    A simple example using a default react-bootstrap navbar:
    ```jsx
    class MyNavBar extends Component {
    render() {
    return (
    <ScrollInNav scrollInHeight={50}>
    <Navbar inverse collapseOnSelect>
    <Navbar.Header>
    <Navbar.Brand>
    <a href="#">React-Bootstrap</a>
    </Navbar.Brand>
    <Navbar.Toggle />
    </Navbar.Header>
    <Navbar.Collapse>
    <Nav>
    <NavItem eventKey={1} href="#">Link</NavItem>
    <NavItem eventKey={2} href="#">Link</NavItem>
    <NavDropdown eventKey={3} title="Dropdown" id="basic-nav-dropdown">
    <MenuItem eventKey={3.1}>Action</MenuItem>
    <MenuItem eventKey={3.2}>Another action</MenuItem>
    <MenuItem eventKey={3.3}>Something else here</MenuItem>
    <MenuItem divider/>
    <MenuItem eventKey={3.3}>Separated link</MenuItem>
    </NavDropdown>
    </Nav>
    <Nav pullRight>
    <NavItem eventKey={1} href="#">Link Right</NavItem>
    <NavItem eventKey={2} href="#">Link Right</NavItem>
    </Nav>
    </Navbar.Collapse>
    </Navbar>
    </ScrollInNav>
    );
    }
    }
    ```