props
然后更新状态(以及相关的CSS)。
import React from "react";
import PropTypes from "prop-types";
export default class Draggable extends React.Component {
constructor(props) {
super(props);
this.mouseMove = this.mouseMove.bind(this);
this.mouseUp = this.mouseUp.bind(this);
this.beginDrag = this.beginDrag.bind(this);
this.state = {
isDragging: false,
lastX: 0,
lastY: 0
};
}
static propTypes = {
onDrag: PropTypes.func.isRequired,
children: PropTypes.element.isRequired
};
render() {
const child = React.Children.only(this.props.children);
const newChild = React.cloneElement(child, {
onMouseDown: this.beginDrag
});
return newChild;
}
componentDidMount() {
window.addEventListener("mousemove", this.mouseMove.bind(this));
window.addEventListener("mouseup", this.mouseUp.bind(this));
}
componentWillUnmount() {
window.removeEventListener("mousemove", this.mouseMove);
window.removeEventListener("mouseup", this.mouseUp);
}
mouseMove(e) {
if (this.state.isDragging) {
const deltas = {
x: e.clientX - this.state.lastX,
y: e.clientY - this.state.lastY
};
this.setState({
lastX: e.clientX,
lastY: e.clientY
});
this.props.onDrag(deltas);
}
};
mouseUp() {
if (this.state.isDragging) {
this.setState({
isDragging: false
});
}
};
beginDrag(e) {
this.setState({
isDragging: true,
lastX: e.clientX,
lastY: e.clientY
});
};
}
使用示例:
import React from "react";
import Draggable from "./Draggable";
export default class SomeComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
translateX: 0,
translateY: 0
};
}
render() {
const style = {
top: this.state.translateY,
left: this.state.translateX
};
return (
<Draggable onDrag={this.onDrag}>
<div className="someComponent">
<div className="dragContainer" style={style}>
<div className="block">
hello world
</div>
<div className="block">
hello world
</div>
<div className="block">
hello world
</div>
</div>
</div>
</Draggable>
);
}
onDrag = (deltas) => {
this.setState(state => ({
translateX: state.translateX + deltas.x,
translateY: state.translateY + deltas.y
}));
};
}
相关SCS:
.someComponent {
display: block;
width: 100%;
height: 100%;
position: relative;
.dragContainer {
position: absolute;
}
.block {
display: inline-block:
}
}
问题
拖动确实起作用,在某种意义上,当我拖动容器时
.dragContainer
问题是,当我开始从任何子元素(比如
.block
s) 一。我可以通过测试
e.target
Draggable.beginDrag
,但我不知道用什么来测试它。理想情况下我会比较
针对传入的子元素
但既然是虚拟的DOM,我敢肯定它不会起作用。
我应该比较什么
e、 目标
用什么?我读过
React.createRef
但我不知道如何在这种情况下使用它。