我一直在尝试在react中实现可拖动的div,基本上,如果我在移动设备上,我会使用鼠标来点击并拖动元素,甚至是手指。 问题是,当我将鼠标移得太快并且光标离开div的区域时,该元素停止了拖动。就像我没有足够快地更新div的位置以跟上光标速度。 知道如何解决这个问题吗?
我也一直在使用顶部和左侧位置来更新div的位置,而使用CSS translatex / y会有任何优势吗? 有什么不同?
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
pos: {
x:0,
y:0,
},
rel: {
x:0,
y:0
},
dragging : false
};
this.draggable = React.createRef()
}
onTouchStart = e => {
const touch = e.touches[0]
const posTop = this.draggable.current.offsetTop
const posLeft = this.draggable.current.offsetLeft
this.setState({
dragging: true,
rel: {
x: touch.clientX - posLeft,
y: touch.clientY - posLeft
}
})
e.stopPropagation()
}
onTouchMove = e => {
if (!this.state.dragging) return
const touch = e.touches[0]
this.setState({
pos: {
x: touch.clientX - this.state.rel.x,
y: touch.clientY - this.state.rel.y
}
})
e.stopPropagation()
e.preventDefault()
}
onTouchEnd = e => {
this.setState({dragging: false})
}
onMouseDown = (e) => {
// only left mouse button
if (e.button !== 0) return
const posTop = this.draggable.current.offsetTop
const posLeft = this.draggable.current.offsetLeft
console.log(e.pageX,': pagex ', e.pageY, ' : and pagey')
console.log(posTop, ': posTop', posLeft, ' : posY')
console.log('resultLeft :', e.pageX - posLeft, 'resultTop :', e.pageY - posTop)
this.setState({
dragging: true,
rel: {
x: e.pageX - posLeft,
y: e.pageY - posTop
}
})
e.stopPropagation()
e.preventDefault()
}
onMouseUp = (e) => {
this.setState({dragging: false})
e.stopPropagation()
e.preventDefault()
}
onMouseMove = (e) => {
if (!this.state.dragging) return
this.setState({
pos: {
x: e.pageX - this.state.rel.x,
y: e.pageY - this.state.rel.y
}
})
e.stopPropagation()
e.preventDefault()
}
render() {
return (
<div style={{position:'relative', backgroundColor:'green', height:'100%', width:'100%'}}>
<div style={{position:'absolute',backgroundColor:'red',
height: '100px', width:'100px',
left: this.state.pos.x + 'px', top: this.state.pos.y + 'px'}}
onTouchStart={this.onTouchStart}
onTouchMove={this.onMouseMove}
onTouchEnd={this.onTouchEnd}
onMouseDown={this.onMouseDown}
onTouchMove={this.onTouchMove}
onMouseMove={this.onMouseMove}
onMouseUp={this.onMouseUp}
ref={this.draggable}
> draggable div
</div>
</div>
);
}
}
render(<App />, document.getElementById('root'));
您可以将代码放在stackblitz上,它可以工作,因此可以尝试。 任何建议都值得欢迎!
Stackblitz链接:https://stackblitz.com/edit/react-draggable-test-oezlsk
答案 0 :(得分:0)
好吧, 找出问题所在。 我将事件onMouseUp onMouseMove分配给div而不是父亲。 此外,由于根div没有任何尺寸,父亲的身高和宽度也不适当。
更新后的有效代码如下
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
pos: {
x:0,
y:0,
},
rel: {
x:0,
y:0
},
dragging : false
};
this.draggable = React.createRef()
}
onTouchStart = e => {
const touch = e.touches[0]
const posTop = this.draggable.current.offsetTop
const posLeft = this.draggable.current.offsetLeft
this.setState({
dragging: true,
rel: {
x: touch.clientX - posLeft,
y: touch.clientY - posLeft
}
})
e.stopPropagation()
}
onTouchMove = e => {
if (!this.state.dragging) return
const touch = e.touches[0]
this.setState({
pos: {
x: touch.clientX - this.state.rel.x,
y: touch.clientY - this.state.rel.y
}
})
e.stopPropagation()
e.preventDefault()
}
onTouchEnd = e => {
this.setState({dragging: false})
}
onMouseDown = (e) => {
// only left mouse button
if (e.button !== 0) return
const posTop = this.draggable.current.offsetTop
const posLeft = this.draggable.current.offsetLeft
console.log(e.pageX,': pagex ', e.pageY, ' : and pagey')
console.log(posTop, ': posTop', posLeft, ' : posY')
console.log('resultLeft :', e.pageX - posLeft, 'resultTop :', e.pageY - posTop)
this.setState({
dragging: true,
rel: {
x: e.pageX - posLeft,
y: e.pageY - posTop
}
})
e.stopPropagation()
e.preventDefault()
}
onMouseUp = (e) => {
this.setState({dragging: false})
e.stopPropagation()
e.preventDefault()
}
onMouseMove = (e) => {
if (!this.state.dragging) return
this.setState({
pos: {
x: e.pageX - this.state.rel.x,
y: e.pageY - this.state.rel.y
}
})
e.stopPropagation()
e.preventDefault()
}
render() {
return (
<div onMouseUp={this.onMouseUp} onMouseMove={this.onMouseMove} style={{position:'relative', backgroundColor:'green', height:'120%', width:'120%'}}>
<div style={{position:'absolute',backgroundColor:'red',
height: '100px', width:'100px',
left: this.state.pos.x + 'px', top: this.state.pos.y + 'px'}}
onTouchStart={this.onTouchStart}
onTouchMove={this.onMouseMove}
onTouchEnd={this.onTouchEnd}
onMouseDown={this.onMouseDown}
onTouchMove={this.onTouchMove}
ref={this.draggable}
> draggable div
</div>
</div>
);
}
}
render(<App />, document.getElementById('root'));