Skip to content

Commit

Permalink
Merge branch 'ChristianDavis-feature/throttle'
Browse files Browse the repository at this point in the history
  • Loading branch information
falcon1kr committed Mar 24, 2017
2 parents b3976f4 + e2aca65 commit d3363eb
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 29 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ Props
- `intervalDelay`: (default `1500`) integer, number of milliseconds between checking the element's position in relation the the window viewport. Making this number too low will have a negative impact on performance.
- `scrollCheck`: (default: `false`) by making this true, the scroll listener is enabled.
- `scrollDelay`: (default: `250`) is the debounce rate at which the check is triggered. Ex: 250ms after the user stopped scrolling.
- `scrollThrottle`: (default: `-1`) by specifying a value > -1, you are enabling throttle instead of the delay to trigger checks on scroll event. Throttle supercedes delay.
- `resizeCheck`: (default: `false`) by making this true, the resize listener is enabled. Resize listener only listens to the window.
- `resizeDelay`: (default: `250`) is the debounce rate at which the check is triggered. Ex: 250ms after the user stopped resizing.
- `resizeThrottle`: (default: `-1`) by specifying a value > -1, you are enabling throttle instead of the delay to trigger checks on resize event. Throttle supercedes delay.
- `containment`: (optional) element to use as a viewport when checking visibility. Default behaviour is to use the browser window as viewport.
- `delayedCall`: (default `false`) if is set to true, wont execute on page load ( prevents react apps triggering elements as visible before styles are loaded )

Expand Down
2 changes: 1 addition & 1 deletion example/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var Example = React.createClass({
<div className='before'></div>
<VisibilitySensor
scrollCheck
scrollDelay={100}
scrollThrottle={100}
intervalDelay={8000}
containment={this.props.containment}
onChange={this.onChange}
Expand Down
20 changes: 11 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@
"react-dom": "^0.14.0 || ^15.0.0"
},
"devDependencies": {
"browserify": "^14.0.0",
"browserify-shim": "^3.8.13",
"es5-shim": "^4.5.9",
"gh-pages": "^0.12.0",
"karma": "^1.4.1",
"karma-chrome-launcher": "^2.0.0",
"karma-mocha": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.2",
"mocha": "^3.2.0",
"browserify": "^5.11.2",
"browserify-shim": "^3.8.12",
"es5-shim": "^4.1.0",
"gh-pages": "^0.2.0",
"karma": "^0.12.31",
"karma-chrome-launcher": "^0.1.4",
"karma-mocha": "^0.1.9",
"karma-phantomjs-launcher": "^0.1.4",
"mocha": "^1.21.4",
"react": "^0.14.0 || ^15.0.0",
"react-dom": "^0.14.0 || ^15.0.0",
"reactify": "^1.1.1",
"uglifyjs": "^2.4.10"
},
Expand Down
56 changes: 37 additions & 19 deletions visibility-sensor.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ module.exports = React.createClass({
}),
scrollCheck: React.PropTypes.bool,
scrollDelay: React.PropTypes.number,
scrollThrottle: React.PropTypes.number,
resizeCheck: React.PropTypes.bool,
resizeDelay: React.PropTypes.number,
resizeThrottle: React.PropTypes.number,
intervalCheck: React.PropTypes.bool,
intervalDelay: React.PropTypes.number,
containment: containmentPropType,
children: React.PropTypes.element,
minTopValue: React.PropTypes.number
minTopValue: React.PropTypes.number,
},

getDefaultProps: function () {
Expand All @@ -42,10 +44,12 @@ module.exports = React.createClass({
minTopValue: 0,
scrollCheck: false,
scrollDelay: 250,
scrollThrottle: -1,
resizeCheck: false,
resizeDelay: 250,
resizeThrottle: -1,
intervalCheck: true,
intervalDelay: 1500,
intervalDelay: 100,
delayedCall: false,
offset: {},
containment: null,
Expand All @@ -61,6 +65,7 @@ module.exports = React.createClass({
},

componentDidMount: function () {
this.node = ReactDOM.findDOMNode(this);
if (this.props.active) {
this.startWatching();
}
Expand All @@ -83,26 +88,35 @@ module.exports = React.createClass({
return this.props.containment || window;
},

addEventListenerWithDebounce: function (target, event, delay) {
addEventListener: function (target, event, delay, throttle) {
if (!this.debounceCheck) {
this.debounceCheck = {};
}

var timeout;
var func;

var debounce = function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
context.check.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, delay || 0);
var later = function () {
timeout = null;
this.check();
}.bind(this);

if (throttle > -1) {
func = function () {
if (!timeout) {
timeout = setTimeout(later, throttle || 0);
}
};
} else {
func = function () {
clearTimeout(timeout);
timeout = setTimeout(later, delay || 0);
};
}

var info = {
target: target,
fn: debounce,
fn: func,
getLastTimeout: function () {
return timeout;
},
Expand All @@ -120,16 +134,21 @@ module.exports = React.createClass({
}

if (this.props.scrollCheck) {
this.addEventListenerWithDebounce(
this.getContainer(), 'scroll', this.props.scrollDelay
this.addEventListener(
this.getContainer(),
'scroll',
this.props.scrollDelay,
this.props.scrollThrottle
);
}

if (this.props.resizeCheck) {
this.addEventListenerWithDebounce(
window, 'resize', this.props.resizeDelay
this.addEventListener(
window,
'resize',
this.props.resizeDelay,
this.props.resizeThrottle
);
}

// if dont need delayed call, check on load ( before the first interval fires )
!this.props.delayedCall && this.check();
Expand Down Expand Up @@ -160,10 +179,9 @@ module.exports = React.createClass({
* Check if the element is within the visible viewport
*/
check: function () {
var el = ReactDOM.findDOMNode(this);
var el = this.node;
var rect;
var containmentRect;

// if the component has rendered to null, dont update visibility
if (!el) {
return this.state;
Expand Down

0 comments on commit d3363eb

Please sign in to comment.