New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-lazyload

Package Overview
Dependencies
Maintainers
1
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-lazyload - npm Package Compare versions

Comparing version

to
2.0.0-beta2

lib/utils/rateLimit.js

349

lib/index.js

@@ -8,2 +8,8 @@ /**

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
exports['default'] = createLazyLoad;
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

@@ -29,207 +35,236 @@

var _utilsDebounce = require('./utils/debounce');
var _utilsRateLimit = require('./utils/rateLimit');
var _utilsDebounce2 = _interopRequireDefault(_utilsDebounce);
var rateLimitMethods = _interopRequireWildcard(_utilsRateLimit);
var listeners = [];
var pending = [];
var SUPPORTED_EVENTS = ['scroll', 'resize', 'wheel', 'mousewheel'];
/**
* Check if `component` is visible in overflow container `parent`
* @param {node} component React component
* @param {node} parent component's scroll parent
* @return {bool}
* Create a LazyLoad component configured by options
* @param {String} options.eventType Events that LazyLoad should listen to, a string of white space separated event types
* @param {String} options.rateLimit The rate limit method, can be `debounce` or `throttle`
* @param {Number} options.wait The freqeuency of rate limit checking
* @return {React} The configured lazyload component
*/
var checkOverflowVisible = function checkOverflowVisible(component, parent) {
var node = _reactDom2['default'].findDOMNode(component);
var scrollTop = parent.scrollTop();
function createLazyLoad() {
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var _options$eventType = options.eventType;
var eventType = _options$eventType === undefined ? 'scroll' : _options$eventType;
var _options$rateLimit = options.rateLimit;
var rateLimit = _options$rateLimit === undefined ? 'debounce' : _options$rateLimit;
var _options$wait = options.wait;
var wait = _options$wait === undefined ? 300 : _options$wait;
var _node$getBoundingClientRect = node.getBoundingClientRect();
var events = eventType.split(' ');
if (!events.every(function (e) {
return SUPPORTED_EVENTS.indexOf(e) > -1;
})) {
console.warn('[react-lazyload] Only %s events are recommended!', SUPPORTED_EVENTS.join(', '));
}
var elementHeight = _node$getBoundingClientRect.height;
var listeners = [];
var pending = [];
var offsets = Array.isArray(component.props.offset) ? component.props.offset : [component.props.offset, component.props.offset]; // Be compatible with previous API
var elementTop = node.offsetTop;
/**
* Check if `component` is visible in overflow container `parent`
* @param {node} component React component
* @param {node} parent component's scroll parent
* @return {bool}
*/
var checkOverflowVisible = function checkOverflowVisible(component, parent) {
var node = _reactDom2['default'].findDOMNode(component);
return elementTop < scrollTop + offsets[0] && elementTop + elementHeight + offsets[1] > scrollTop;
};
var scrollTop = parent.scrollTop();
/**
* Check if `component` is visible in document
* @param {node} component React component
* @return {bool}
*/
var checkNormalVisible = function checkNormalVisible(component) {
var node = _reactDom2['default'].findDOMNode(component);
var _node$getBoundingClientRect = node.getBoundingClientRect();
var _node$getBoundingClientRect2 = node.getBoundingClientRect();
var elementHeight = _node$getBoundingClientRect.height;
var top = _node$getBoundingClientRect2.top;
var bottom = _node$getBoundingClientRect2.bottom;
var offsets = Array.isArray(component.props.offset) ? component.props.offset : [component.props.offset, component.props.offset]; // Be compatible with previous API
var elementTop = node.offsetTop;
var supportPageOffset = window.pageXOffset !== undefined;
var isCSS1Compat = (document.compatMode || '') === 'CSS1Compat';
return elementTop < scrollTop + offsets[0] && elementTop + elementHeight + offsets[1] > scrollTop;
};
var scrollTop = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;
/**
* Check if `component` is visible in document
* @param {node} component React component
* @return {bool}
*/
var checkNormalVisible = function checkNormalVisible(component) {
var node = _reactDom2['default'].findDOMNode(component);
var elementTop = top + scrollTop;
var elementHeight = bottom - top;
var windowInnerHeight = window.innerHeight || document.documentElement.clientHeight;
var _node$getBoundingClientRect2 = node.getBoundingClientRect();
var offsets = Array.isArray(component.props.offset) ? component.props.offset : [component.props.offset, component.props.offset]; // Be compatible with previous API
var top = _node$getBoundingClientRect2.top;
var bottom = _node$getBoundingClientRect2.bottom;
return elementTop < scrollTop + windowInnerHeight + offsets[0] && elementTop + elementHeight + offsets[1] > scrollTop;
};
var supportPageOffset = window.pageXOffset !== undefined;
var isCSS1Compat = (document.compatMode || '') === 'CSS1Compat';
/**
* Detect if element is visible in viewport, if so, set `visible` state to true.
* If `once` prop is provided true, remove component as listener after checkVisible
*
* @param {React} component React component that respond to scroll and resize
*/
var checkVisible = function checkVisible(component) {
var node = _reactDom2['default'].findDOMNode(component);
var parent = _utilsScrollParent2['default'](node);
var isOverflow = parent !== (node.ownerDocument || document);
var scrollTop = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;
var visible = isOverflow ? checkOverflowVisible(component, parent) : checkNormalVisible(component);
var elementTop = top + scrollTop;
var elementHeight = bottom - top;
var windowInnerHeight = window.innerHeight || document.documentElement.clientHeight;
if (visible) {
// Avoid extra render if previously is visible, yeah I mean `render` call,
// not actual DOM render
if (!component.state.visible) {
component._firstTimeVisible = component._firstTimeVisible === undefined;
var offsets = Array.isArray(component.props.offset) ? component.props.offset : [component.props.offset, component.props.offset]; // Be compatible with previous API
return elementTop < scrollTop + windowInnerHeight + offsets[0] && elementTop + elementHeight + offsets[1] > scrollTop;
};
/**
* Detect if element is visible in viewport, if so, set `visible` state to true.
* If `once` prop is provided true, remove component as listener after checkVisible
*
* @param {React} component React component that respond to scroll and resize
*/
var checkVisible = function checkVisible(component) {
var node = _reactDom2['default'].findDOMNode(component);
var parent = _utilsScrollParent2['default'](node);
var isOverflow = parent !== (node.ownerDocument || document);
var visible = isOverflow ? checkOverflowVisible(component, parent) : checkNormalVisible(component);
if (visible) {
// Avoid extra render if previously is visible, yeah I mean `render` call,
// not actual DOM render
if (!component.state.visible) {
component._firstTimeVisible = component._firstTimeVisible === undefined;
component.setState({
visible: true
});
}
if (component.props.once) {
pending.push(component);
}
} else if (component.state.visible) {
if (component._firstTimeVisible !== undefined) {
component._firstTimeVisible = false;
}
component.setState({
visible: true
visible: false
});
}
};
if (component.props.once) {
pending.push(component);
}
} else if (component.state.visible) {
if (component._firstTimeVisible !== undefined) {
component._firstTimeVisible = false;
}
var purgePending = function purgePending() {
pending.forEach(function (component) {
var index = listeners.indexOf(component);
if (index !== -1) {
listeners.splice(index, 1);
}
});
component.setState({
visible: false
});
pending = [];
};
var rateLimitMethod = rateLimitMethods[rateLimit];
if (typeof rateLimitMethod !== 'function') {
console.warn('[react-lazyload] %s is not a valid rate limit type, no rate limit method is applied.', rateLimit);
rateLimitMethod = function (f) {
return f;
};
}
};
var purgePending = function purgePending() {
pending.forEach(function (component) {
var index = listeners.indexOf(component);
if (index !== -1) {
listeners.splice(index, 1);
var lazyLoadHandler = rateLimitMethod(function () {
for (var i = 0; i < listeners.length; ++i) {
var listener = listeners[i];
checkVisible(listener);
}
});
pending = [];
};
// Remove `once` component in listeners
purgePending();
}, wait);
var lazyLoadHandler = _utilsDebounce2['default'](function () {
for (var i = 0; i < listeners.length; ++i) {
var listener = listeners[i];
checkVisible(listener);
}
return (function (_Component) {
_inherits(LazyLoad, _Component);
// Remove `once` component in listeners
purgePending();
}, 300);
_createClass(LazyLoad, null, [{
key: 'propTypes',
value: {
once: _react.PropTypes.bool,
offset: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.arrayOf(_react.PropTypes.number)]),
children: _react.PropTypes.node
},
enumerable: true
}, {
key: 'defaultProps',
value: {
once: false,
offset: 0
},
enumerable: true
}]);
var LazyLoad = (function (_Component) {
_inherits(LazyLoad, _Component);
function LazyLoad(props) {
_classCallCheck(this, LazyLoad);
function LazyLoad(props) {
_classCallCheck(this, LazyLoad);
_Component.call(this, props);
_Component.call(this, props);
if (props.scroll === true && props.wheel === true) {
console && console.warn('[react-lazyload] Don\'t use both `scroll` and `wheel` event in LazyLoad component, pick one!');
this.state = {
visible: false
};
}
this.state = {
visible: false
};
}
LazyLoad.prototype.componentDidMount = function componentDidMount() {
if (listeners.length === 0) {
if (events.indexOf('scroll') > -1) {
_utilsEvent.on(window, 'scroll', lazyLoadHandler);
}
LazyLoad.prototype.componentDidMount = function componentDidMount() {
if (listeners.length === 0) {
if (this.props.scroll) {
_utilsEvent.on(window, 'scroll', lazyLoadHandler);
}
if (events.indexOf('wheel') > -1) {
if (window.hasOwnProperty('onwheel')) {
_utilsEvent.on(window, 'wheel', lazyLoadHandler);
} else {
_utilsEvent.on(window, 'mousewheel', lazyLoadHandler);
}
}
if (this.props.wheel) {
if (window.hasOwnProperty('onwheel')) {
_utilsEvent.on(window, 'wheel', lazyLoadHandler);
} else {
_utilsEvent.on(window, 'mousewheel', lazyLoadHandler);
if (events.indexOf('resize') > -1) {
_utilsEvent.on(window, 'resize', lazyLoadHandler);
}
}
if (this.props.resize) {
_utilsEvent.on(window, 'resize', lazyLoadHandler);
}
}
listeners.push(this);
checkVisible(this);
};
listeners.push(this);
checkVisible(this);
};
LazyLoad.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) {
return nextState.visible;
};
LazyLoad.prototype.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) {
return nextState.visible;
};
LazyLoad.prototype.componentWillUpdate = function componentWillUpdate(nextProps, nextState) {
if (this.state.visible && nextState.visible && this._firstTimeVisible) {
this._firstTimeVisible = false;
}
};
LazyLoad.prototype.componentWillUpdate = function componentWillUpdate(nextProps, nextState) {
if (this.state.visible && nextState.visible && this._firstTimeVisible) {
this._firstTimeVisible = false;
}
};
LazyLoad.prototype.componentWillUnmount = function componentWillUnmount() {
var index = listeners.indexOf(this);
if (index !== -1) {
listeners.splice(index, 1);
}
LazyLoad.prototype.componentWillUnmount = function componentWillUnmount() {
var index = listeners.indexOf(this);
if (index !== -1) {
listeners.splice(index, 1);
}
if (listeners.length === 0) {
_utilsEvent.off(window, 'wheel', lazyLoadHandler);
_utilsEvent.off(window, 'mousewheel', lazyLoadHandler);
_utilsEvent.off(window, 'resize', lazyLoadHandler);
_utilsEvent.off(window, 'scroll', lazyLoadHandler);
}
};
if (listeners.length === 0) {
_utilsEvent.off(window, 'wheel', lazyLoadHandler);
_utilsEvent.off(window, 'mousewheel', lazyLoadHandler);
_utilsEvent.off(window, 'resize', lazyLoadHandler);
_utilsEvent.off(window, 'scroll', lazyLoadHandler);
}
};
LazyLoad.prototype.render = function render() {
return _react2['default'].cloneElement(this.props.children, {
visible: this.state.visible,
firstTimeVisible: this._firstTimeVisible
});
};
LazyLoad.prototype.render = function render() {
return _react2['default'].cloneElement(this.props.children, {
visible: this.state.visible,
firstTimeVisible: this._firstTimeVisible
});
};
return LazyLoad;
})(_react.Component);
}
return LazyLoad;
})(_react.Component);
LazyLoad.propTypes = {
once: _react.PropTypes.bool,
offset: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.arrayOf(_react.PropTypes.number)]),
scroll: _react.PropTypes.bool,
wheel: _react.PropTypes.bool,
resize: _react.PropTypes.bool,
children: _react.PropTypes.node
};
LazyLoad.defaultProps = {
once: false,
offset: 0,
scroll: true,
wheel: false,
resize: false
};
exports['default'] = LazyLoad;
module.exports = exports['default'];
{
"name": "react-lazyload",
"version": "2.0.0-beta1",
"version": "2.0.0-beta2",
"description": "Lazyload your Component, Image or anything matters the performance.",

@@ -5,0 +5,0 @@ "main": "lib/index.js",