react-stickynode
Advanced tools
Comparing version 1.0.1 to 1.0.2
@@ -12,2 +12,3 @@ /** | ||
var classNames = require('classnames'); | ||
var propTypes = React.PropTypes; | ||
var shallowCompare = require('react-addons-shallow-compare'); | ||
@@ -51,2 +52,3 @@ var subscribe = require('subscribe-ui-event').subscribe; | ||
autobind: false, | ||
/** | ||
@@ -60,6 +62,6 @@ * @param {Bool} enabled A switch to enable or disable Sticky. | ||
propTpes: { | ||
enabled: React.PropTypes.bool, | ||
top: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]), | ||
bottomBoundary: React.PropTypes.oneOfType([React.PropTypes.object, // TODO, may remove | ||
React.PropTypes.string, React.PropTypes.number]) | ||
enabled: propTypes.bool, | ||
top: propTypes.oneOfType([propTypes.string, propTypes.number]), | ||
bottomBoundary: propTypes.oneOfType([propTypes.object, // TODO, may remove | ||
propTypes.string, propTypes.number]) | ||
}, | ||
@@ -105,9 +107,10 @@ | ||
getTopPosition: function getTopPosition() { | ||
var self = this; | ||
// TODO, topTarget is for current layout, may remove | ||
var top = this.props.top || this.props.topTarget || 0; | ||
var top = self.props.top || self.props.topTarget || 0; | ||
if (typeof top === 'string') { | ||
if (!this.topTarget) { | ||
this.topTarget = doc.querySelector(top); | ||
if (!self.topTarget) { | ||
self.topTarget = doc.querySelector(top); | ||
} | ||
top = this.getTargetHeight(this.topTarget); | ||
top = self.getTargetHeight(self.topTarget); | ||
} | ||
@@ -126,4 +129,6 @@ return top; | ||
getBottomBoundary: function getBottomBoundary() { | ||
var boundary = this.props.bottomBoundary; | ||
var self = this; | ||
var boundary = self.props.bottomBoundary; | ||
// TODO, bottomBoundary was an object, depricate it later. | ||
@@ -135,6 +140,6 @@ if (typeof boundary === 'object') { | ||
if (typeof boundary === 'string') { | ||
if (!this.bottomBoundaryTarget) { | ||
this.bottomBoundaryTarget = doc.querySelector(boundary); | ||
if (!self.bottomBoundaryTarget) { | ||
self.bottomBoundaryTarget = doc.querySelector(boundary); | ||
} | ||
boundary = this.getTargetBottom(this.bottomBoundaryTarget); | ||
boundary = self.getTargetBottom(self.bottomBoundaryTarget); | ||
} | ||
@@ -144,7 +149,2 @@ return boundary && boundary > 0 ? boundary : Infinity; | ||
changeDirection: function changeDirection(d1, d2) { | ||
d2 = d2 || this.delta; | ||
return d1 !== 0 && d2 !== 0 && d1 > 0 ^ d2 > 0; | ||
}, | ||
reset: function reset() { | ||
@@ -175,5 +175,7 @@ this.setState({ | ||
updateInitialDimension: function updateInitialDimension() { | ||
this.timer = +new Date(); | ||
var outer = this.refs.outer; | ||
var inner = this.refs.inner; | ||
var self = this; | ||
self.timer = +new Date(); | ||
var outer = self.refs.outer; | ||
var inner = self.refs.inner; | ||
var outerRect = outer.getBoundingClientRect(); | ||
@@ -185,5 +187,5 @@ | ||
this.setState({ | ||
top: this.getTopPosition(), | ||
bottom: Math.min(this.state.top + height, winHeight), | ||
self.setState({ | ||
top: self.getTopPosition(), | ||
bottom: Math.min(self.state.top + height, winHeight), | ||
width: width, | ||
@@ -193,3 +195,3 @@ height: height, | ||
y: outerY, | ||
bottomBoundary: this.getBottomBoundary(), | ||
bottomBoundary: self.getBottomBoundary(), | ||
topBoundary: outerY | ||
@@ -233,5 +235,7 @@ }); | ||
update: function update() { | ||
if (this.state.bottomBoundary - this.state.topBoundary <= this.state.height || !this.props.enabled) { | ||
if (this.state.status !== STATUS_ORIGINAL) { | ||
this.reset(); | ||
var self = this; | ||
if (self.state.bottomBoundary - self.state.topBoundary <= self.state.height || !self.props.enabled) { | ||
if (self.state.status !== STATUS_ORIGINAL) { | ||
self.reset(); | ||
} | ||
@@ -242,27 +246,27 @@ return; | ||
var delta = scrollDelta; | ||
var top = scrollTop + this.state.top; | ||
var bottom = scrollTop + this.state.bottom; | ||
var top = scrollTop + self.state.top; | ||
var bottom = scrollTop + self.state.bottom; | ||
if (top <= this.state.topBoundary) { | ||
this.reset(); | ||
} else if (bottom >= this.state.bottomBoundary) { | ||
this.stickyBottom = this.state.bottomBoundary; | ||
this.stickyTop = this.stickyBottom - this.state.height; | ||
this.release(this.stickyTop); | ||
if (top <= self.state.topBoundary) { | ||
self.reset(); | ||
} else if (bottom >= self.state.bottomBoundary) { | ||
self.stickyBottom = self.state.bottomBoundary; | ||
self.stickyTop = self.stickyBottom - self.state.height; | ||
self.release(self.stickyTop); | ||
} else { | ||
if (this.state.height > winHeight) { | ||
if (self.state.height > winHeight) { | ||
// In this case, Sticky is larger then screen | ||
switch (this.state.status) { | ||
switch (self.state.status) { | ||
case STATUS_ORIGINAL: | ||
this.release(this.state.y); | ||
this.stickyTop = this.state.y; | ||
this.stickyBottom = this.stickyTop + this.state.height; | ||
self.release(self.state.y); | ||
self.stickyTop = self.state.y; | ||
self.stickyBottom = self.stickyTop + self.state.height; | ||
break; | ||
case STATUS_RELEASED: | ||
if (delta > 0 && bottom > this.stickyBottom) { | ||
if (delta > 0 && bottom > self.stickyBottom) { | ||
// scroll down | ||
this.fix(this.state.bottom - this.state.height); | ||
} else if (delta < 0 && top < this.stickyTop) { | ||
self.fix(self.state.bottom - self.state.height); | ||
} else if (delta < 0 && top < self.stickyTop) { | ||
// scroll up | ||
this.fix(this.state.top); | ||
this.fix(self.state.top); | ||
} | ||
@@ -272,10 +276,10 @@ break; | ||
var isChanged = true; | ||
if (delta > 0 && this.state.pos === this.state.top) { | ||
if (delta > 0 && self.state.pos === self.state.top) { | ||
// scroll down | ||
this.stickyTop = top - delta; | ||
this.stickyBottom = this.stickyTop + this.state.height; | ||
} else if (delta < 0 && this.state.pos === this.state.bottom - this.state.height) { | ||
self.stickyTop = top - delta; | ||
self.stickyBottom = self.stickyTop + self.state.height; | ||
} else if (delta < 0 && self.state.pos === self.state.bottom - self.state.height) { | ||
// up | ||
this.stickyBottom = bottom - delta; | ||
this.stickyTop = this.stickyBottom - this.state.height; | ||
self.stickyBottom = bottom - delta; | ||
self.stickyTop = self.stickyBottom - self.state.height; | ||
} else { | ||
@@ -286,3 +290,3 @@ isChanged = false; | ||
if (isChanged) { | ||
this.release(this.stickyTop); | ||
self.release(self.stickyTop); | ||
} | ||
@@ -292,6 +296,6 @@ break; | ||
} else { | ||
this.fix(this.state.top); | ||
self.fix(self.state.top); | ||
} | ||
} | ||
this.delta = delta; | ||
self.delta = delta; | ||
}, | ||
@@ -311,5 +315,6 @@ | ||
componentDidMount: function componentDidMount() { | ||
if (this.props.enabled) { | ||
this.updateInitialDimension(); | ||
this.subscribers = [subscribe('scrollStart', this.handleScrollStart, { useRAF: true }), subscribe('scroll', this.handleScroll, { useRAF: true, enableScrollInfo: true }), subscribe('resize', this.handleResize, { enableResizeInfo: true })]; | ||
var self = this; | ||
if (self.props.enabled) { | ||
self.updateInitialDimension(); | ||
self.subscribers = [subscribe('scrollStart', self.handleScrollStart.bind(self), { useRAF: true }), subscribe('scroll', self.handleScroll.bind(self), { useRAF: true, enableScrollInfo: true }), subscribe('resize', self.handleResize.bind(self), { enableResizeInfo: true })]; | ||
} | ||
@@ -331,13 +336,14 @@ }, | ||
render: function render() { | ||
var self = this; | ||
// TODO, "overflow: auto" prevents collapse, need a good way to get children height | ||
var style = { | ||
overflow: 'hidden', | ||
position: this.state.status === STATUS_FIXED ? 'fixed' : 'relative', | ||
top: this.state.status === STATUS_FIXED ? '0' : '' | ||
position: self.state.status === STATUS_FIXED ? 'fixed' : 'relative', | ||
top: self.state.status === STATUS_FIXED ? '0' : '' | ||
}; | ||
// always use translate3d to enhance the performance | ||
this.translate(style, this.state.pos); | ||
if (this.state.status !== STATUS_ORIGINAL) { | ||
style.width = this.state.width; | ||
self.translate(style, self.state.pos); | ||
if (self.state.status !== STATUS_ORIGINAL) { | ||
style.width = self.state.width; | ||
} | ||
@@ -347,7 +353,7 @@ | ||
'div', | ||
{ ref: 'outer', className: classNames('sticky-outer-wrapper', this.props.className) }, | ||
{ ref: 'outer', className: classNames('sticky-outer-wrapper', self.props.className) }, | ||
React.createElement( | ||
'div', | ||
{ ref: 'inner', className: 'sticky-inner-wrapper', style: style }, | ||
this.props.children | ||
self.props.children | ||
) | ||
@@ -354,0 +360,0 @@ ); |
{ | ||
"name": "react-stickynode", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "A performant and comprehensive React sticky", | ||
@@ -33,3 +33,3 @@ "main": "index.js", | ||
"classnames": "^2.0.0", | ||
"react-addons-shallow-compare": "0.14.x", | ||
"react-addons-shallow-compare": "^0.14.2", | ||
"subscribe-ui-event": "^0.2.0" | ||
@@ -62,9 +62,9 @@ }, | ||
"pre-commit": "^1.0.0", | ||
"react-dom": "0.14.x", | ||
"react": "0.14.x", | ||
"react-dom": "^0.14.2", | ||
"react": "^0.14.2", | ||
"xunit-file": "^0.0.8" | ||
}, | ||
"peerDependencies": { | ||
"react": "0.14.x", | ||
"react-dom": "0.14.x" | ||
"react": "^0.14.2", | ||
"react-dom": "^0.14.2" | ||
}, | ||
@@ -71,0 +71,0 @@ "precommit": [ |
@@ -31,3 +31,3 @@ # react-stickynode | ||
The sticky uses Modernizr `csstransforms3d` and `prefixed` features to detect IE8/9, so it can downgrade to not use transform3d. | ||
The sticky uses Modernizr `csstransforms3d` and `prefixed` features to detect IE8/9, so it can downgrade not to use transform3d. | ||
@@ -43,7 +43,14 @@ http://modernizr.com/download/?-csstransforms3d-prefixed | ||
```js | ||
var Sticky = require('react-stickynode'); | ||
<Sticky top='#header' bottomBoundary='#content'> | ||
<YourComponent/> | ||
</Sticky> | ||
``` | ||
### Props | ||
- enabled {Bool} - The switch to enable or disable Sticky (true by default). | ||
- top {Number/String} - The offset from the top of window where the top of the element will be when sticky state is triggered (0 by default). If it is a selector to a target (via `querySelector()`), the offset will be the height of the target. | ||
- bottomBoundary {Number/String} - The offset from the top of document which release state will be triggered when the bottom of the element reaches at. If it is a selector to a target (via `querySelector()`), the offset will be the bottom of the target. | ||
- `enabled {Boolean}` - The switch to enable or disable Sticky (true by default). | ||
- `top {Number/String}` - The offset from the top of window where the top of the element will be when sticky state is triggered (0 by default). If it is a selector to a target (via `querySelector()`), the offset will be the height of the target. | ||
- `bottomBoundary {Number/String}` - The offset from the top of document which release state will be triggered when the bottom of the element reaches at. If it is a selector to a target (via `querySelector()`), the offset will be the bottom of the target. | ||
@@ -50,0 +57,0 @@ ## Install & Development |
30062
606
71