UNPKG

@6thquake/react-material

Version:

React components that implement Google's Material Design.

329 lines (269 loc) 9.6 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _react = _interopRequireWildcard(require("react")); var _withStyles = _interopRequireDefault(require("../styles/withStyles")); var _icons = require("@material-ui/icons"); var _propTypes = _interopRequireDefault(require("prop-types")); var styles = { rmBackTopContent: { paddingTop: '10px', transition: 'all .3s cubic-bezier(.645,.045,.355,1)', height: '40px', width: '40px', borderRadius: '20px', backgroundColor: 'rgba(64,64,64,.4)', color: '#fff', textAlign: 'center' }, backTop: { zIndex: '10000000', position: 'fixed', height: '40px!important', width: '40px!important', cursor: 'pointer' }, windowBtn: { right: '100px', bottom: '50px' } }; var BackTop = /*#__PURE__*/ function (_React$Component) { (0, _inherits2.default)(BackTop, _React$Component); function BackTop(props) { var _this; (0, _classCallCheck2.default)(this, BackTop); _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BackTop).call(this, props)); _this.scrollHandler = _this.handleScroll.bind((0, _assertThisInitialized2.default)(_this)); _this.returnTop = function (e) { e.preventDefault(); e.nativeEvent.stopImmediatePropagation(); e.stopPropagation(); _this.container === window ? document.body.scrollTop = document.documentElement.scrollTop = 0 : _this.container.scrollTop = 0; _this.props.onClick(e); }; _this.state = { visibilityHeight: props.visibilityHeight, customButton: props.children, onClick: props.onClick, showBackTop: false, fixLeft: 0, fixTop: 0 }; try { if (_this.state.customButton) { _react.default.Children.only(_this.state.customButton); // 如果自定义按钮,验证是否只有唯一的根元素 } } catch (err) { console.log(err); } return _this; } (0, _createClass2.default)(BackTop, [{ key: "hasScrollbar", value: function hasScrollbar() { if (this.container === window) { return document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight); } return this.container.scrollHeight > this.container.clientHeight || this.container.offsetHeight > this.container.clientHeight; } }, { key: "getScrollTop", value: function getScrollTop() { var scrollPos; if (this.container === window) { if (window.pageYOffset) { scrollPos = window.pageYOffset; } else if (document.compatMode && document.compatMode != 'BackCompat') { scrollPos = document.documentElement.scrollTop; } else if (document.body) { scrollPos = document.body.scrollTop; } } else { scrollPos = this.container.scrollTop; } return scrollPos; } }, { key: "handleScroll", value: function handleScroll(event) { if (this.hasScrollbar()) { var scrollTop = this.getScrollTop(); if (scrollTop > this.state.visibilityHeight) { this.setState({ showBackTop: true }); } else { this.setState({ showBackTop: false }); } } if (this.container != window) { this.resetPosition(); } } }, { key: "componentDidMount", value: function componentDidMount() { this.showWindowBtn = false; var idSel = this.props.container; var customButton = this.state.customButton; this.container = document.querySelector(idSel) || window; if (this.hasScrollbar()) { var scrollTop = this.getScrollTop(); if (scrollTop > this.state.visibilityHeight) { this.setState({ showBackTop: true }); } } if (this.container === window) { this.showWindowBtn = true; } window.addEventListener('scroll', this.scrollHandler); // 不管是什么类型的button 都需要监听浏览器滚动 if (this.container != window) { this.container.addEventListener('scroll', this.scrollHandler); } if (this.container != window) { this.resetPosition(); } } }, { key: "resetPosition", value: function resetPosition() { var customButton = this.state.customButton; var top = 0; // container 下边界距窗口最上面的距离 var left = 0; // container 右边界距窗口最左边的距离 var fixLeft = 0; // backTop button 相对位置 left值 var fixTop = 0; // backTop button 相对位置 top值 top = this.container.getBoundingClientRect().bottom; left = this.container.getBoundingClientRect().right; if (customButton) { customWith = customButton.getBoundingClientRect().width; // 自定义按钮本身的宽度 customHeight = customButton.getBoundingClientRect().height; // 自定义按钮本身的高度 if (customWith > 40) { customWith = 40; } if (customHeight > 40) { customHeight = 40; } fixLeft = left - customWith - 100; fixLTop = top - customHeight - 50; } else { fixLeft = left - 40 - 100; fixTop = top - 40 - 50; } this.setState({ fixLeft: fixLeft, fixTop: fixTop }); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.container.removeEventListener('scroll', this.ths, false); } }, { key: "render", value: function render() { var _this2 = this; var classes = this.props.classes; var _this$state = this.state, showBackTop = _this$state.showBackTop, customButton = _this$state.customButton, fixLeft = _this$state.fixLeft, fixTop = _this$state.fixTop; var windowBtnNoCustom = _react.default.createElement("div", { onClick: function onClick(e) { return _this2.returnTop(e); }, className: "".concat(classes.backTop, " ").concat(classes.windowBtn) }, _react.default.createElement("div", { className: classes.rmBackTopContent }, _react.default.createElement(_icons.Publish, null))); var windowBtnCustom = _react.default.createElement("div", { style: { bottom: '100px' }, onClick: function onClick(e) { return _this2.returnTop(e); }, className: "".concat(classes.backTop, " ").concat(classes.windowBtn) }, customButton); var containerBtnNoCustom = _react.default.createElement("div", { style: { left: "".concat(fixLeft, "px"), top: "".concat(fixTop, "px") }, onClick: function onClick(e) { return _this2.returnTop(e); }, className: classes.backTop }, _react.default.createElement("div", { className: classes.rmBackTopContent }, _react.default.createElement(_icons.Publish, null))); var containerBtnCustom = _react.default.createElement("div", { style: { bottom: '100px', left: "".concat(fixLeft, "px"), top: "".concat(fixTop, "px") }, onClick: function onClick(e) { return _this2.returnTop(e); }, className: classes.backTop }, customButton); var backTopButton = windowBtnNoCustom; if (this.showWindowBtn) { if (customButton) { backTopButton = windowBtnCustom; } else { backTopButton = windowBtnNoCustom; } } else if (customButton) { backTopButton = containerBtnCustom; } else { backTopButton = containerBtnNoCustom; } // const backTopButton = this.showWindowBtn ? (customButton ? windowBtnCustom : windowBtnNoCustom) :( customButton? containerBtnCustom : containerBtnNoCustom); return showBackTop ? backTopButton : null; } }]); return BackTop; }(_react.default.Component); BackTop.propTypes = { /** * Override or extend the styles applied to the component. * See [CSS API](#css-api) below for more details. */ classes: _propTypes.default.object.isRequired, /** * Id selector, element that needs to be listened the scroll event, the default value is window */ container: _propTypes.default.string, /** * callback function when click BackTop button */ onClick: _propTypes.default.func, /** * show BackTop button when scroll to this height */ visibilityHeight: _propTypes.default.number }; BackTop.defaultProps = { visibilityHeight: 300 }; var _default = (0, _withStyles.default)(styles)(BackTop); exports.default = _default;