Skip to content

Commit

Permalink
Bump version 1.0.1 -> 1.0.2
Browse files Browse the repository at this point in the history
- Add event object and scope to onEnter/onLeave calls
- Allow React 0.14.0-beta peerDependency
- Always remove window resize event listener
  • Loading branch information
lencioni committed Aug 17, 2015
1 parent 0443d22 commit 6964953
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 39 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## master (unreleased)
## 1.0.2

- Add event object and scope to onEnter/onLeave calls
- Allow React 0.14.0-beta peerDependency
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-waypoint",
"main": "build/npm/waypoint.js",
"version": "1.0.1",
"version": "1.0.2",
"homepage": "https://github.com/brigade/react-waypoint",
"description": "A React component to execute a function whenever you scroll to an element.",
"moduleType": [
Expand Down
80 changes: 44 additions & 36 deletions build/npm/waypoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ var Waypoint = React.createClass({
onEnter: PropTypes.func,
onLeave: PropTypes.func,
// threshold is percentage of the height of the visible part of the
// scrollable parent (e.g. 0.1)
threshold: PropTypes.number },

_wasVisible: false,
// scrollable ancestor (e.g. 0.1)
threshold: PropTypes.number
},

/**
* @return {Object}
Expand All @@ -26,12 +25,13 @@ var Waypoint = React.createClass({
return {
threshold: 0,
onEnter: function onEnter() {},
onLeave: function onLeave() {} };
onLeave: function onLeave() {}
};
},

componentDidMount: function componentDidMount() {
this.scrollableParent = this._findScrollableParent();
this.scrollableParent.addEventListener('scroll', this._handleScroll);
this.scrollableAncestor = this._findScrollableAncestor();
this.scrollableAncestor.addEventListener('scroll', this._handleScroll);
window.addEventListener('resize', this._handleScroll);
this._handleScroll();
},
Expand All @@ -42,25 +42,27 @@ var Waypoint = React.createClass({
},

componentWillUnmount: function componentWillUnmount() {
if (this.scrollableParent) {
// At the time of unmounting, the scrollable parent might no longer exist.
// Guarding against this prevents the following error:
if (this.scrollableAncestor) {
// At the time of unmounting, the scrollable ancestor might no longer
// exist. Guarding against this prevents the following error:
//
// Cannot read property 'removeEventListener' of undefined
this.scrollableParent.removeEventListener('scroll', this._handleScroll);
window.removeEventListener('resize', this._handleScroll);
this.scrollableAncestor.removeEventListener('scroll', this._handleScroll);
}
window.removeEventListener('resize', this._handleScroll);
},

_wasVisible: false,

/**
* Traverses up the DOM to find a parent container which has an overflow style
* that allows for scrolling.
* Traverses up the DOM to find an ancestor container which has an overflow
* style that allows for scrolling.
*
* @return {Object} the closest parent element with an overflow style that
* @return {Object} the closest ancestor element with an overflow style that
* allows for scrolling. If none is found, the `window` object is returned
* as a fallback.
*/
_findScrollableParent: function _findScrollableParent() {
_findScrollableAncestor: function _findScrollableAncestor() {
var node = this.getDOMNode();

while (node.parentNode) {
Expand All @@ -71,20 +73,25 @@ var Waypoint = React.createClass({
continue;
}

var _style = window.getComputedStyle(node);
var overflowY = _style.getPropertyValue('overflow-y') || _style.getPropertyValue('overflow');
var style = window.getComputedStyle(node);
var overflowY = style.getPropertyValue('overflow-y') || style.getPropertyValue('overflow');

if (overflowY === 'auto' || overflowY === 'scroll') {
return node;
}
}

// A scrollable parent element was not found, which means that we need to do
// stuff on window.
// A scrollable ancestor element was not found, which means that we need to
// do stuff on window.
return window;
},

_handleScroll: function _handleScroll() {
/**
* @param {Object} event the native scroll event coming from the scrollable
* ancestor, or resize event coming from the window. Will be undefined if
* called by a React lifecyle method
*/
_handleScroll: function _handleScroll(event) {
var isVisible = this._isVisible();

if (this._wasVisible === isVisible) {
Expand All @@ -93,9 +100,9 @@ var Waypoint = React.createClass({
}

if (isVisible) {
this.props.onEnter();
this.props.onEnter.call(this, event);
} else {
this.props.onLeave();
this.props.onLeave.call(this, event);
}

this._wasVisible = isVisible;
Expand All @@ -105,38 +112,39 @@ var Waypoint = React.createClass({
* @param {Object} node
* @return {Number}
*/
_distanceToTopOfScrollableParent: function _distanceToTopOfScrollableParent(node) {
if (this.scrollableParent !== window && !node.offsetParent) {
throw new Error('The scrollable parent of Waypoint needs to have positioning to ' + 'properly determine position of Waypoint (e.g. `position: relative;`)');
_distanceToTopOfScrollableAncestor: function _distanceToTopOfScrollableAncestor(node) {
if (this.scrollableAncestor !== window && !node.offsetParent) {
throw new Error('The scrollable ancestor of Waypoint needs to have positioning to ' + 'properly determine position of Waypoint (e.g. `position: relative;`)');
}

if (node.offsetParent === this.scrollableParent || !node.offsetParent) {
if (node.offsetParent === this.scrollableAncestor || !node.offsetParent) {
return node.offsetTop;
} else {
return node.offsetTop + this._distanceToTopOfScrollableParent(node.offsetParent);
return node.offsetTop + this._distanceToTopOfScrollableAncestor(node.offsetParent);
}
},

/**
* @return {boolean} true if scrolled down almost to the end of the scrollable
* parent element.
* ancestor element.
*/
_isVisible: function _isVisible() {
var waypointTop = this._distanceToTopOfScrollableParent(this.getDOMNode());
var contextHeight = undefined,
contextScrollTop = undefined;
var waypointTop = this._distanceToTopOfScrollableAncestor(this.getDOMNode());
var contextHeight = undefined;
var contextScrollTop = undefined;

if (this.scrollableParent === window) {
if (this.scrollableAncestor === window) {
contextHeight = window.innerHeight;
contextScrollTop = window.pageYOffset;
} else {
contextHeight = this.scrollableParent.offsetHeight;
contextScrollTop = this.scrollableParent.scrollTop;
contextHeight = this.scrollableAncestor.offsetHeight;
contextScrollTop = this.scrollableAncestor.scrollTop;
}

var thresholdPx = contextHeight * this.props.threshold;

var isAboveBottom = contextScrollTop + contextHeight >= waypointTop - thresholdPx;
var contextBottom = contextScrollTop + contextHeight;
var isAboveBottom = contextBottom >= waypointTop - thresholdPx;
var isBelowTop = contextScrollTop <= waypointTop + thresholdPx;

return isAboveBottom && isBelowTop;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-waypoint",
"version": "1.0.1",
"version": "1.0.2",
"description": "A React component to execute a function whenever you scroll to an element.",
"main": "build/npm/waypoint.js",
"repository": {
Expand Down

0 comments on commit 6964953

Please sign in to comment.