77 lines
1.7 KiB
JavaScript
77 lines
1.7 KiB
JavaScript
var React = require('react');
|
|
|
|
var _listeners = [];
|
|
|
|
module.exports = {
|
|
|
|
isInViewport: function() {
|
|
|
|
var el = React.findDOMNode(this);
|
|
|
|
if(!el) return false;
|
|
|
|
var rect = el.getBoundingClientRect();
|
|
|
|
var viewportHeight = global.window.innerHeight || global.document.documentElement.clientHeight;
|
|
var viewportWidth = global.window.innerWidth || global.document.documentElement.clientWidth;
|
|
|
|
return (
|
|
rect.bottom >= 0 &&
|
|
rect.right >= 0 &&
|
|
rect.top <= viewportHeight &&
|
|
rect.left <= viewportWidth
|
|
);
|
|
|
|
},
|
|
|
|
componentDidMount: function() {
|
|
|
|
if(typeof this.onInViewport === 'function') {
|
|
|
|
_listeners.push(this);
|
|
|
|
if( this.isInViewport() ) {
|
|
this.onInViewport();
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
componentWillUnmount: function() {
|
|
var index = _listeners.indexOf(this);
|
|
if(index !== -1) return _listeners.splice(index, 1);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
var computeComponentsVisibilityDebounced = debounce(computeComponentsVisibility, 100);
|
|
|
|
// Start listening for changes
|
|
window.document.addEventListener('scroll', computeComponentsVisibilityDebounced, true);
|
|
window.addEventListener('resize', computeComponentsVisibilityDebounced);
|
|
|
|
function computeComponentsVisibility() {
|
|
_listeners.forEach(function(listener) {
|
|
if( listener.isInViewport() ) {
|
|
listener.onInViewport();
|
|
}
|
|
});
|
|
}
|
|
|
|
function debounce(func, wait, immediate) {
|
|
var timeout;
|
|
return function() {
|
|
var context = this, args = arguments;
|
|
var later = function() {
|
|
timeout = null;
|
|
if (!immediate) func.apply(context, args);
|
|
};
|
|
var callNow = immediate && !timeout;
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(later, wait);
|
|
if (callNow) func.apply(context, args);
|
|
};
|
|
}
|