我正试图从头开始在Vuejs中创建可拖动对象。但我现在面临两个问题。
- 拖动结束时,对象仅捕捉到目标坐标立即
- 我已尝试通过设置删除"重影图像"拖动时不透明度为0%,但这似乎不起作用
这是我现在正在处理的代码。https://jsfiddle.net/wmsk1npb/
<div id="app">
{{x}}/{{y}} ....... {{coordinates}}
<div class="bubbleMenuContainer" :style="coordinates" draggable="true" @drag="move" @dragend="set">
Test
</div>
</div>
new Vue({
el: '#app',
data: {
x:0,
y:0,
coordinates:{
top: "100px",
left: "100px",
opacity: "100%",
}
},
methods:{
move(event){
this.x = event.clientX;
this.y = event.clientY;
this.coordinates.left = event.clientX + "px";
this.coordinates.top = event.clientY + "px";
this.coordinates.opacity = "0%;"
},
set(event){
this.coordinates.left = event.clientX + "px";
this.coordinates.top = event.clientY + "px";
this.coordinates.opacity = "100%;"
}
}
})
.bubbleMenuContainer{
position: absolute;
border-radius: 100px;
background-color: lightcoral;
width: 30px;
height: 30px;
padding: 10px;
}
我从未尝试过使用draggable="true"
,相反,我会使用鼠标上下移动(以及触摸设备所需的触摸对应物(
这给了你更多的控制权,这样你就不会显示重叠的项目了。
这个想法是。。。
- 在数据中,跟踪位置,开始拖动位置(x,y(以及是否拖动项目
- 在鼠标向下设置isDragging为true并存储开始拖动位置x,y坐标
- 在鼠标移动时,如果
isDragging === true
根据startdrag和当前clientXY之间的差异更新位置 - 鼠标向上移动时,将isDragging设置为false
您还可以通过动态添加和删除监听器mousemove和mouseup来改进这一点。因为您希望在文档上使用鼠标移动侦听器(而不是元素,这是更好的方法(
我最近为新的vue3组合api写了一篇关于这一点的文章,网址是https://dev.to/dasdaniel/vue3-compisition-api-craeting-a-draggable-element-fo6
因为它是针对vue3的,所以它不支持复制粘贴,但重要的部分在这里:
const onMouseDown = e => {
let { clientX, clientY } = e;
position.dragStartX = clientX - position.x;
position.dragStartY = clientY - position.y;
position.isDragging = true;
document.addEventListener("mouseup", onMouseUp);
document.addEventListener("mousemove", onMouseMove);
};
const onMouseMove = e => {
let { clientX, clientY } = e;
position.x = clientX - position.dragStartX;
position.y = clientY - position.dragStartY;
};
const onMouseUp = e => {
let { clientX, clientY } = e;
position.isDragging = false;
position.dragStartX = null;
position.dragStartY = null;
document.removeEventListener("mouseup", onMouseUp);
document.removeEventListener("mousemove", onMouseMove);
};
HTML属性"draggable"用于指示元素是否可拖动。请注意,这是本机浏览器行为,您可以在此处阅读更多信息(https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/draggable)。这就是浏览器的行为,也是你在试图拖动气泡时看到"重影图像"的原因。
我认为您使用了一种更简单的方法来使元素可拖动。参考我在JSFiddle上准备的这个样本(https://jsfiddle.net/r8emga0u/1/)。
<div id="app" @mouseup="up" @mousemove="move">
{{x}}/{{y}} ....... {{coordinates}}
<div class="bubbleMenuContainer" :style="coordinates" @mousedown="down">
Test
</div>
</div>
down(e) {
this.bubbleMenuClickState = true;
this.offset = [
e.target.offsetLeft - e.clientX,
e.target.offsetTop - e.clientY
];
},
up(e) {
this.bubbleMenuClickState = false;
},
move(e) {
if (this.bubbleMenuClickState) {
this.coordinates.left = (e.clientX + this.offset[0]) + "px";
this.coordinates.top = (e.clientY + this.offset[1]) + "px";
}
}
步骤:
- 将"mousedown"侦听器附加到元素,可以计算气泡相对于其父对象的偏移量。如果没有这一点,最初点击气泡可能会将其位置设置为0,0,因为还没有触发鼠标移动事件
- 将一个"mouseup"侦听器连接到气泡的父对象(在本例中为#应用程序(,以检测用户何时释放点击。从而防止mousemove事件移动气泡
- 如果用户点击并按住并拖动气泡,则附加"mousemove"监听器来更新气泡的位置