- 30
- 0
想问一个最基本的react实现拖曳面板的实现~
有一个add的button,鼠标点击之后会弹出新面板,这个面板是通过绝对定位每次都定位在同一位置上的,想实现鼠标点击这个面板之后的拖曳效果,
我的实现思路大概就是监听onmousedown,onmousemove和onmouseup,然后用一个flag,先点击,获取到点击时的鼠标的坐标,将flag设为true,然后在mousemove的时候将每一次的位置给styleObj,最后mouseup的时候将flag设为false,
实现拖曳的效果貌似也不太对。。不太平滑,而且有时候方向是反的,可是我计算这个styleObj的left和top属性值应该没错(move的clientX-点击时得到的clientX+原始的left值)。
var index=0;
class Panel extends React.Component{
constructor (props){
super(props);
this.state={
styleObj:{
top: 100,
left:100
},
mouseXY:{
//这个获取的是每一次点击panel时的鼠标的坐标
x: 0,
y: 0
},
isTouch:false
};
this.handleMouseDown = this.handleMouseDown.bind(this);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.handleMouseUp = this.handleMouseUp
}
handleMouseDown(e){
//获取当前鼠标按下的位置,并把它放到stat里面去,并且要设置一个flag,使得只有触发了点击,才会
console.log(e.clientX);
this.setState(
{
isTouch:!this.state.isTouch,
mouseXY:{
x:e.clientX,
y:e.clientY
}
},function(){
//callback,只有在上面改完才执行
this.printInfo();
}
);
}
printInfo(){
console.log(this.state.mouseXY.x); //输出此时的mouseXY的x
console.log(this.state.isTouch); //输出true
}
handleMouseMove(e){
//先判断是否已点击,然后再需要让这个panel的x,y随滑动的位置发生相应的改变
if(this.state.isTouch){
this.setState({
styleObj:{
left:this.state.styleObj.left+e.clientX-this.state.mouseXY.x,
top:this.state.styleObj.top+e.clientY-this.state.mouseXY.y,
}
})
}
}
handleMouseUp(e){
this.setState({
isTouch:!this.state.isTouch
})
}
render(){
return (
<div className="box" style={this.state.styleObj} onMouseDown={this.handleMouseDown} onMouseMove={this.handleMouseMove} onMouseUp={this.handleMouseUp}></div>
)
}
}
class App extends React.Component{
constructor(props){
super(props);
this.state={listitem:[]};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
index++;
this.setState({
listitem :this.state.listitem.concat(<Panel key={index}>{index}</Panel>)
});
}
render(){
return (
<div>
<button onClick={this.handleClick}>
Add
</button>
<div>
{this.state.listitem}
</div>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
在第一条评论下面的是我修改之后不会有bug的,想问下这两者的区别是什么~因为貌似给left和top的数值都是一样的啊
- 共 0 条
- 全部回答
-
烟敛寒林 普通会员 1楼
在React中,我们可以使用第三方库React-Draggable来实现面板拖曳的功能。React-Draggable是一个基于React的拖放库,它提供了多种拖放控件和各种拖放策略,可以用于实现拖拽操作。
以下是一个简单的例子:
```jsx import React, { useState } from 'react'; import Draggable from 'react-draggable';
const Panel = () => { const [dragged, setDragged] = useState(null);
const handleDragStart = (event) => { setDragged(event.target); };
const handleDrag = (event) => { const { clientX, clientY } = event; const dragedElement = document.getElementById('draggable'); if (dragged) { dragedElement.style.left =
${clientX}px; dragedElement.style.top =${clientY}px; } };return (
); };Drag me
export default Panel; ```
在这个例子中,我们首先在
handleDragStart函数中设置了一个状态变量dragged,它存储了我们正在拖动的元素。然后在handleDrag函数中,我们获取了拖动事件的clientX和clientY坐标,以及我们正在拖动的元素的id。如果dragged已经存在,我们就更新其left和top样式,以显示我们正在拖动的元素。注意,这个例子使用了
id来唯一标识我们的元素。在实际使用中,你可能需要使用其他的标识符,比如元素的class或style属性。
- 扫一扫访问手机版
回答动态

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器更新之后。服务器里面有部分玩家要重新创建角色是怎么回事啊?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题函数计算不同地域的是不能用内网吧?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题ARMS可以创建多个应用嘛?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题在ARMS如何申请加入公测呀?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题前端小程序接入这个arms具体是如何接入监控的,这个init方法在哪里进行添加?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器刚到期,是不是就不能再导出存档了呢?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器的游戏版本不兼容 尝试更新怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器服务器升级以后 就链接不上了,怎么办?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器转移以后服务器进不去了,怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器修改参数后游戏进入不了,是什么情况?预计能赚取 0积分收益
- 回到顶部
- 回到顶部

