higimo-scroll-spy
Version:
Компонент следит за тем, до какого элемента доскроллил клиент и передает сообщение в другой элемент
94 lines (76 loc) • 2.01 kB
JavaScript
var React = require('react')
var createReactClass = require('create-react-class')
var debounce = require('throttle-debounce/debounce');
var ScrollSpy = createReactClass({
getPropTypes: function() {
return {
name : PropTypes.string,
update : PropTypes.function,
interval : PropTypes.number,
children : PropTypes.oneOfType([
PropTypes.element,
PropTypes.arrayOf(PropTypes.element)
]),
}
},
getDefaultProps: function() {
return {
interval : 50,
children : null,
name : 'default',
update : () => {
console.warn('standard definition of update')
},
}
},
getInitialState: function() {
return {
visible : false,
throttle : debounce(this.props.interval, this.isComponentVisible),
}
},
componentDidMount: function() {
window.addEventListener('scroll', this.state.throttle);
window.addEventListener('resize', this.state.throttle);
this.isComponentVisible()
},
componentWillUnmount: function() {
window.removeEventListener('scroll', this.state.throttle);
window.removeEventListener('resize', this.state.throttle);
},
setNodeRef: function(ref) {
this.nodeRef = ref
},
getPropsToRender: function() {
var props = {}
this.props.className !== null && (props.className = this.props.className)
this.props.style !== null && (props.style = this.props.style)
this.props.offset !== 0 && (props.offset = this.props.offset)
return props
},
getChildren: function() {
return React.Children.map(
this.props.children,
child => React.cloneElement(
child,
{
visible: this.state.visible
}
)
)
},
isComponentVisible: function() {
var rect = this.nodeRef.getBoundingClientRect()
this.props.update(this.props.name, rect)
},
render: function() {
var divProps = this.getPropsToRender()
divProps.ref = this.setNodeRef
return React.createElement(
'div',
divProps,
this.getChildren()
)
},
})
module.exports = ScrollSpy