Created
June 4, 2015 21:57
-
-
Save alexaivars/56df0273c2439e4d9783 to your computer and use it in GitHub Desktop.
sticky wrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var React = require('react'); | |
var util = { | |
// findPos() by quirksmode.org | |
// Finds the absolute position of an element on a page | |
findPos: function (obj) { | |
/*jshint -W084 */ | |
var curleft = 0, | |
curtop = 0; | |
if (obj.offsetParent) { | |
do { | |
curleft += obj.offsetLeft; | |
curtop += obj.offsetTop; | |
} while (obj = obj.offsetParent); | |
} | |
return [curleft, curtop]; | |
}, | |
// getPageScroll() by quirksmode.org | |
// Finds the scroll position of a page | |
getPageScroll: function () { | |
var xScroll, yScroll; | |
if (window.self && window.self.pageYOffset) { | |
yScroll = window.self.pageYOffset; | |
xScroll = window.self.pageXOffset; | |
} else if (document.documentElement && document.documentElement.scrollTop) { | |
yScroll = document.documentElement.scrollTop; | |
xScroll = document.documentElement.scrollLeft; | |
} else if (document.body) {// all other Explorers | |
yScroll = document.body.scrollTop; | |
xScroll = document.body.scrollLeft; | |
} | |
return [xScroll, yScroll]; | |
}, | |
// Finds the position of an element relative to the viewport. | |
findPosRelativeToViewport: function (obj) { | |
var objPos = this.findPos(obj); | |
var scroll = this.getPageScroll(); | |
return [ objPos[0] - scroll[0], objPos[1] - scroll[1] ]; | |
} | |
}; | |
class Sticky extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
fix: false | |
}; | |
} | |
componentDidMount() { | |
window.addEventListener('scroll', this.handleScroll.bind(this), false); | |
window.addEventListener('resize', this.handleResize.bind(this)); | |
} | |
componentWillUnmount() { | |
window.removeEventListener('scroll', this.handleScroll.bind(this), false); | |
window.removeEventListener('resize', this.handleResize.bind(this)); | |
} | |
handleResize(){ | |
this.checkPositions(); | |
} | |
handleScroll() { | |
this.checkPositions(); | |
} | |
checkPositions(){ | |
var pos = util.findPosRelativeToViewport(React.findDOMNode(this)); | |
if (pos[1]<=this.props.offsetTop){ | |
this.setState({fix: true}); | |
} else { | |
this.setState({fix: false}); | |
} | |
} | |
render() { | |
var divStyle; | |
if (this.state.fix) { | |
divStyle = { | |
display: 'block', | |
position: 'fixed', | |
top: this.props.offsetTop | |
}; | |
return ( | |
<div style={{zIndex : this.props.zIndex, position:'relative', width:'100%'}}> | |
<div ref='original' key='original' className={this.props.className} style={divStyle} >{this.props.children}</div> | |
</div> | |
); | |
} else { | |
divStyle = { | |
display: 'block', | |
position: 'relative' | |
}; | |
return ( | |
<div style={{zIndex : this.props.zIndex, position:'relative', width:'100%'}}> | |
<div ref='original' key='original' style={divStyle}>{this.props.children}</div> | |
</div> | |
); | |
} | |
} | |
} | |
Sticky.defaultProps = { | |
offsetTop: 0, | |
className: '', | |
zIndex: 9999 | |
}; | |
Sticky.propTypes = { | |
offsetTop: React.PropTypes.number, | |
zIndex: React.PropTypes.number, | |
className: React.PropTypes.string | |
}; | |
module.exports = Sticky; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment