.m-gotop {
position: fixed;
z-index: 100;
bottom: .45rem;
right: .1rem;
width: .44rem;
height: .44rem;
border-radius: .44rem;
background: rgba(255, 255, 255, 0.9);
color: #00bcd4;
font-size: .25rem;
text-align: center;
}
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
const whiteSpace = ' ';
/**
* 添加类名
*
* @param {any} node
* @param {any} className
*/
function addClass(node, className) {
node.className = (node.className + whiteSpace + className).split(/\s+/).filter(function (item, index, source) {
return source.lastIndexOf(item) === index;
}).join(whiteSpace);
}
/**
* 去除类名
*
* @param {any} node
* @param {any} className
*/
function removeClass(node, className) {
className = whiteSpace + className.replace(/\s+/g, whiteSpace) + whiteSpace;
node.className = node.className.split(/\s+/).filter(function (originClassName) {
return className.indexOf(whiteSpace + originClassName + whiteSpace) === -1;
}).join(whiteSpace);
}
import './style.css';
//创建根节点组件
class GoTop extends Component {
constructor(props) {
super(props);
//显示状态
this.isShow = false;
this.containerClass = ['m-gotop'].join(' ');
}
componentDidMount() {
this.wrapper = document.createElement('div');
addClass(this.wrapper, this.containerClass + ' hide');
document.body.appendChild(this.wrapper);
this.appendWrapperToDocBody();
}
componentWillUnmount() {
document.body.removeChild(this.wrapper);
}
appendWrapperToDocBody() {
ReactDOM.unstable_renderSubtreeIntoContainer(
this,
<div onClick={() => {
this.props.onPress();
}}>Top</div>,
this.wrapper
);
}
setDeltaY(y) {
let {deltaY} = this.props;
//如果已经显示,直接返回
if (y > deltaY && this.isShow) {
return;
}
//如果小于范围,且未显示也返回
if (y < deltaY && !this.isShow) {
return;
}
if (y > deltaY) {
this.isShow = true;
removeClass(this.wrapper, 'hide');
} else {
this.isShow = false;
addClass(this.wrapper, this.containerClass + ' hide');
}
}
render() {
return null;
}
}
//组件的实例的默认属性,可以让组件在没有接收到任何值的时候,可以独立运行。
GoTop.defaultProps = {
deltaY: 100,
onPress: () => {
}
};
//对传递过来的属性进行类型检查,从而避免出现一些低级的BUG,它输出了一些列的验证器,可以用来确保接收的参数是有效的。
GoTop.propTypes = {
/** 阈值 */
deltaY: PropTypes.number,
/** 点击按钮的函数 */
onPress: PropTypes.func.isRequired
/**
* // 你可以声明一个 prop 是一个特定的 JS 原始类型。
// 默认情况下,这些都是可选的。
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
// 任何东西都可以被渲染:numbers, strings, elements,或者是包含这些类型的数组(或者是片段)。
optionalNode: PropTypes.node,
// 一个 React 元素。
optionalElement: PropTypes.element,
// 你也可以声明一个 prop 是类的一个实例。
// 使用 JS 的 instanceof 运算符。
optionalMessage: PropTypes.instanceOf(Message),
// 你可以声明 prop 是特定的值,类似于枚举
optionalEnum: PropTypes.oneOf(['News', 'Photos']),
// 一个对象可以是多种类型其中之一
optionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),
// 一个某种类型的数组
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
// 属性值为某种类型的对象
optionalObjectOf: PropTypes.objectOf(PropTypes.number),
// 一个特定形式的对象
optionalObjectWithShape: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
}),
// 你可以使用 `isRequired' 链接上述任何一个,以确保在没有提供 prop 的情况下显示警告。
requiredFunc: PropTypes.func.isRequired,
// 任何数据类型的值
requiredAny: PropTypes.any.isRequired,
*/
};
export default GoTop;
网友评论