From 2caf9a63d6ac56c6a9fa197baee5f5a245ac0290 Mon Sep 17 00:00:00 2001 From: Arkadiusz Zalewski Date: Sun, 8 Oct 2017 20:20:03 +0200 Subject: [PATCH] Added handleScroll method. --- src/ResizeDetector.jsx | 155 ++++++++++++++++++++++++++--------------- 1 file changed, 98 insertions(+), 57 deletions(-) diff --git a/src/ResizeDetector.jsx b/src/ResizeDetector.jsx index 7c14ffb..20df93d 100644 --- a/src/ResizeDetector.jsx +++ b/src/ResizeDetector.jsx @@ -1,58 +1,99 @@ -import React, { Component, PropTypes } from 'react'; - -const OBJECT_STYLE = { - display: 'block', - position: 'absolute', - top: 0, - left: 0, - height: '100%', - width: '100%', - overflow: 'hidden', - pointerEvents: 'none', - zIndex: -1, -}; - -export default class ResizeDetector extends Component { - static propTypes = { - onResize: PropTypes.func.isRequired, - }; - - constructor(props) { - super(props); - this.state = { - isMounted: false, - }; - this.setDOMElement = this.setDOMElement.bind(this); - this.handleLoad = this.handleLoad.bind(this); - } - - componentDidMount() { - this.setState({ - isMounted: true, - }); - } - - componentWillUnmount() { - this.domElement.contentDocument.defaultView.removeEventListener('resize', this.props.onResize); - } - - setDOMElement(domElement) { - this.domElement = domElement; - } - - handleLoad() { - this.domElement.contentDocument.defaultView.addEventListener('resize', this.props.onResize); - } - - render() { - return ( - - ); - } +import React, {Component, PropTypes} from 'react' +import ResizeDetector from './ResizeDetector' + +export default class OverflowDetector extends Component { + static propTypes = { + onOverflowChange: PropTypes.func, + children: PropTypes.node, + style: PropTypes.object, + className: PropTypes.string, + } + + static defaultProps = { + style: {}, + } + + constructor(props) { + super(props) + this.isOverflowed = false + this.domElement = null + this.scrollState = { + atTop: true, + atBottom: true, + atLeft: true, + atRight: true, + } + this.setDOMElement = this.setDOMElement.bind(this) + this.checkOverflow = this.checkOverflow.bind(this) + this.handleScroll = this.handleScroll.bind(this) + } + + componentDidMount() { + this.checkOverflow() + } + + componentDidUpdate() { + this.checkOverflow() + } + + setDOMElement(domElement) { + this.domElement = domElement + } + + checkOverflow() { + const isOverflowed = + this.domElement.scrollWidth > this.domElement.clientWidth || + this.domElement.scrollHeight > this.domElement.clientHeight + + if (isOverflowed !== this.isOverflowed) { + this.isOverflowed = isOverflowed + if (this.props.onOverflowChange) { + this.props.onOverflowChange(isOverflowed) + } + if (!isOverflowed) { + this.handleScroll() + } + } + } + + handleScroll() { + const { + clientHeight, + clientWidth, + scrollTop, + scrollLeft, + scrollHeight, + scrollWidth, + } = this.domElement + const atTop = scrollTop === 0 + const atBottom = scrollTop + clientHeight === scrollHeight + const atLeft = scrollLeft === 0 + const atRight = scrollLeft + clientWidth === scrollWidth + const s = this.scrollState + if ( + s.atTop !== atTop || + s.atBottom !== atBottom || + s.atLeft !== atLeft || + s.atRight !== atRight + ) { + const scrollState = {atTop, atBottom, atLeft, atRight} + this.scrollState = scrollState + this.props.onScrolled(scrollState) + } + } + + render() { + const {style, className, children, onScrolled} = this.props + return ( +
+ {children} + +
+ ) + } }