@6thquake/react-material
Version:
React components that implement Google's Material Design.
329 lines (269 loc) • 9.6 kB
JavaScript
"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;