Skip to content

Commit 085a4b7

Browse files
committed
Add ScrollListenerMixin
1 parent 9e80b90 commit 085a4b7

File tree

7 files changed

+107
-3
lines changed

7 files changed

+107
-3
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.DS_Store
2+
.module-cache
23
node_modules
File renamed without changes.

ScrollBlocker.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/** @jsx React.DOM */
2+
var React = require('react');
3+
var cx = require('react/lib/cx');
4+
5+
var ScrollBlocker = React.createClass({displayName: 'ScrollBlocker',
6+
7+
getDefaultProps: function () {
8+
return {
9+
active: false
10+
};
11+
},
12+
13+
render: function () {
14+
var classes = cx({
15+
'ScrollBlocker': this.props.active
16+
});
17+
18+
return (
19+
React.DOM.div( {className:cx(classes, this.props.className)},
20+
this.props.children
21+
)
22+
);
23+
}
24+
});
25+
26+
module.exports = ScrollBlocker;

ScrollListenerMixin.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
var win = typeof window !== 'undefined' ? window : false;
2+
3+
var getScrollTop = function () {
4+
return win.pageYOffset || win.document.scrollTop || win.document.body.scrollTop || 0;
5+
}
6+
7+
var ScrollListenerMixin = {
8+
9+
getDefaultProps: function() {
10+
return {
11+
endScrollTimeout: 300
12+
};
13+
},
14+
15+
getInitialState: function() {
16+
return {
17+
scrollTop: 0,
18+
isScrolling: false
19+
};
20+
},
21+
22+
componentDidMount: function () {
23+
if (win) {
24+
win.addEventListener('scroll', this._onPageScroll);
25+
}
26+
},
27+
28+
componentWillUnmount: function () {
29+
if (win) {
30+
win.removeEventListener('scroll', this._onPageScroll);
31+
}
32+
},
33+
34+
shouldComponentUpdate: function(nextProps, nextState) {
35+
return (
36+
nextState.scrollTop !== this.state.scrollTop ||
37+
nextState.isScrolling !== this.state.isScrolling
38+
)
39+
},
40+
41+
_onPageScrollEnd: function () {
42+
var scrollTop = getScrollTop();
43+
if (scrollTop === this.state.scrollTop) {
44+
win.clearTimeout(this._pageScrollTimeout);
45+
this.setState({ isScrolling: false });
46+
47+
if (typeof this.props.onPageScrollEnd === 'function') {
48+
this.props.onPageScrollEnd(scrollTop, isScrolling);
49+
}
50+
}
51+
},
52+
53+
_onPageScroll: function () {
54+
var scrollTop = getScrollTop();
55+
56+
this.setState({
57+
scrollTop: scrollTop,
58+
isScrolling: true
59+
});
60+
61+
win.clearTimeout(this._pageScrollTimeout);
62+
this._pageScrollTimeout = win.setTimeout(this._onPageScrollEnd, this.props.endScrollTimeout);
63+
64+
if (typeof this.props.onPageScroll === 'function') {
65+
this.props.onPageScroll(scrollTop, isScrolling);
66+
}
67+
}
68+
};
69+
70+
module.exports = ScrollListenerMixin;

index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
var ScrollBlocker = require('src/ScrollBlocker');
1+
var ScrollBlocker = require('./ScrollBlocker');
2+
var ScrollListenerMixin = require('./ScrollListenerMixin');
23

34
module.exports = {
4-
ScrollBlocker: ScrollBlocker
5+
ScrollBlocker: ScrollBlocker,
6+
ScrollListenerMixin: ScrollListenerMixin
57
}
File renamed without changes.

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"description": "A set of components that react to page scrolling",
55
"main": "index.js",
66
"scripts": {
7-
"test": "echo \"Error: no test specified\" && exit 1"
7+
"test": "echo \"Error: no test specified\" && exit 1",
8+
"build": "./node_modules/react-tools/bin/jsx -x jsx ./jsx ."
89
},
910
"repository": {
1011
"type": "git",
@@ -24,5 +25,9 @@
2425
"homepage": "https://github.com/jeroencoumans/react-scroll-components",
2526
"peerDependencies": {
2627
"react": "^0.10.0"
28+
},
29+
"dependencies": {},
30+
"devDependencies": {
31+
"react-tools": "^0.10.0"
2732
}
2833
}

0 commit comments

Comments
 (0)