UNPKG

tingle-load-more

Version:
136 lines (108 loc) 3.28 kB
/** * LoadMore Component for tingle * @author yize * * Copyright 2014-2015, Tingle Team, Alinw. * All rights reserved. */ const Context = require('tingle-context'); const classnames = require('classnames'); const LOADING = 'loading'; const NOMORE = 'noMore'; class LoadMore extends React.Component { constructor(props) { super(props); this.state = { load: LOADING } } componentDidMount() { const t = this; document.addEventListener('scroll', this._onScroll.bind(t), false); document.addEventListener('resize', this._onScroll.bind(t), false); } componentWillUnmount() { const t = this; document.removeEventListener('scroll', this._onScroll.bind(t), false); document.removeEventListener('resize', this._onScroll.bind(t), false); } loaded() { this.setState({load: LOADING}); this.isLoading = false; this._unLock(); // 如果 loaded 之后,也应该检测下是否 inViewPort 如果是的话,应该再触发一次加载。 this._onScroll(); } // lock loading() { this.isLoading = true; } _canLoad() { return !this.isLoading && this.state.load !== NOMORE; } noMore() { this.setState({load: NOMORE}); this._unLock(); } render() { const t = this; let text = ''; switch (t.state.load) { case LOADING: text = t.props.loadingText; break; case NOMORE: text = t.props.noMoreText; } return (<div ref="root" className={classnames({ 'tLoadMore': true, [t.props.className]: !!t.props.className, [t.state.load]: !!t.state.load })}>{text}</div>); } _isVisible(el, offset) { const t = this; offset = t.props.offset >= 50 ? t.props.offset : 50; // Check if the element is visible // https://github.com/jquery/jquery/blob/740e190223d19a114d5373758127285d14d6b71e/src/css/hiddenVisibleSelectors.js if (!el.offsetWidth || !el.offsetHeight) { return false; } const eltRect = el.getBoundingClientRect(); return eltRect.top < document.documentElement.clientHeight + offset; } _onScroll() { const t = this; const el = React.findDOMNode(t.refs.root); if (!el || !t._canLoad()) { return; } if (t._isVisible(el, this.offset)) { t.loading(); t._handleLoadEvents(); } } _handleLoadEvents() { this.props.onLoadMore && this.props.onLoadMore({loadState: this.state.load}) } _isLoading() { return this.isLoading; } _unLock() { this.isLoading = false; } } LoadMore.defaultProps = { offset: 50, onLoadMore: Context.noop, loadingText: '正在加载中…', noMoreText: '没有啦!' }; // http://facebook.github.io/react/docs/reusable-components.html LoadMore.propTypes = { offset: React.PropTypes.number, onLoadMore: React.PropTypes.func, loadingText: React.PropTypes.string, noMoreText: React.PropTypes.string }; module.exports = LoadMore;