From 73fe5cc2c3873da6986d739170690c93a39cf31d Mon Sep 17 00:00:00 2001 From: afc163 Date: Mon, 29 Feb 2016 16:44:38 +0800 Subject: [PATCH] support affix bottom, close #1000 --- components/affix/demo/bottom.md | 17 +++++++++ components/affix/demo/offset.md | 2 +- components/affix/index.jsx | 63 +++++++++++++++++++++------------ components/affix/index.md | 3 +- 4 files changed, 60 insertions(+), 25 deletions(-) create mode 100644 components/affix/demo/bottom.md diff --git a/components/affix/demo/bottom.md b/components/affix/demo/bottom.md new file mode 100644 index 0000000000..72b360588f --- /dev/null +++ b/components/affix/demo/bottom.md @@ -0,0 +1,17 @@ +# 下方固定 + +- order: 2 + +固定在屏幕下方 + +--- + +````jsx +import { Affix, Button } from 'antd'; + +ReactDOM.render( + + + +, mountNode); +```` diff --git a/components/affix/demo/offset.md b/components/affix/demo/offset.md index 561c070ab1..f1aba9ccc1 100644 --- a/components/affix/demo/offset.md +++ b/components/affix/demo/offset.md @@ -10,7 +10,7 @@ import { Affix, Button } from 'antd'; ReactDOM.render( - + , mountNode); diff --git a/components/affix/index.jsx b/components/affix/index.jsx index 0d6314c24f..3e1685be28 100644 --- a/components/affix/index.jsx +++ b/components/affix/index.jsx @@ -33,43 +33,60 @@ function getOffset(element) { } const Affix = React.createClass({ - - getDefaultProps() { - return { - offset: 0, - }; - }, - propTypes: { - offset: React.PropTypes.number, + offsetTop: React.PropTypes.number, + offsetBottom: React.PropTypes.number, }, getInitialState() { return { - affix: false, affixStyle: null, }; }, handleScroll() { - const affix = this.state.affix; + let { offsetTop, offsetBottom } = this.props; const scrollTop = getScroll(window, true); const elemOffset = getOffset(ReactDOM.findDOMNode(this)); + const elemSize = { + width: ReactDOM.findDOMNode(this.refs.fixedNode).offsetWidth, + height: ReactDOM.findDOMNode(this.refs.fixedNode).offsetHeight, + }; - if (!affix && (elemOffset.top - this.props.offset) < scrollTop) { - this.setState({ - affix: true, - affixStyle: { - top: this.props.offset, - left: elemOffset.left, - width: ReactDOM.findDOMNode(this).offsetWidth, - }, - }); + const offsetMode = {}; + if (typeof offsetTop !== 'number' && typeof offsetBottom !== 'number') { + offsetMode.top = true; + offsetTop = 0; + } else { + offsetMode.top = typeof offsetTop === 'number'; + offsetMode.bottom = typeof offsetBottom === 'number'; } - if (affix && (elemOffset.top - this.props.offset) > scrollTop) { + if (scrollTop > elemOffset.top - offsetTop && offsetMode.top) { + // Fixed Top + if (!this.state.affixStyle) { + this.setState({ + affixStyle: { + position: 'fixed', + top: offsetTop, + left: elemOffset.left, + }, + }); + } + } else if (scrollTop < elemOffset.top + elemSize.height + offsetBottom - window.innerHeight && + offsetMode.bottom) { + // Fixed Bottom + if (!this.state.affixStyle) { + this.setState({ + affixStyle: { + position: 'fixed', + bottom: offsetBottom, + left: elemOffset.left, + }, + }); + } + } else if (this.state.affixStyle) { this.setState({ - affix: false, affixStyle: null, }); } @@ -92,12 +109,12 @@ const Affix = React.createClass({ render() { const className = classNames({ [this.props.className]: this.props.className, - 'ant-affix': this.state.affix, + 'ant-affix': this.state.affixStyle, }); return (
-
+
{this.props.children}
diff --git a/components/affix/index.md b/components/affix/index.md index 89c2af0c05..9c7a89f9ec 100644 --- a/components/affix/index.md +++ b/components/affix/index.md @@ -18,4 +18,5 @@ | 成员 | 说明 | 类型 | 默认值 | |-------------|----------------|--------------------|--------------| -| offset | 达到指定偏移量后触发 | Number | 0 | +| offsetTop | 距离窗口顶部达到指定偏移量后触发 | Number | | +| offsetBottom | 距离窗口底部达到指定偏移量后触发 | Number | |