首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Drag‘n’Drag:当我单击元素时,元素没有停留在其原始位置

Drag‘n’Drag:当我单击元素时,元素没有停留在其原始位置
EN

Stack Overflow用户
提问于 2021-04-16 05:57:01
回答 1查看 37关注 0票数 1

我正在为我的一个项目编写我自己的拖放功能,我遇到了一个问题。我所有的“可拖动”元素都在一个带有display:flex的容器中。在其中一个元素上发生mousedown事件时,我将position设置为absolute,这样就可以在拖动时设置该元素的lefttop属性。下面是我正在做的事情:

代码语言:javascript
复制
let container = document.querySelector("#big-container")
var dragging = false;
var draggedObject;
let shiftX=0;
let shiftY=0;
document.querySelectorAll(".draggable").forEach((draggable,index) => {
    draggable.style.order = index;
    draggable.draggable =false;
    draggable.ondragstart = ()=>{return false}
    draggable.addEventListener("mousedown",ev =>{
        draggedObject = draggable;
        shiftX = ev.offsetX+5;
        shiftY = ev.offsetY+5;
        draggable.style.position = "absolute";
        draggable.style.left = (ev.clientX - shiftX) + 'px';
        draggable.style.top = (ev.clientY - shiftY) + 'px';
        dragging = true;
        let placeholder = document.createElement("div");
        placeholder.id = "placeholder";
        placeholder.style.order = draggable.style.order;
        container.appendChild(placeholder);
    })

})

document.addEventListener("mousemove", ev =>{
    if(dragging){
        draggedObject.style.left = ev.clientX - shiftX + 'px';
        draggedObject.style.top = ev.clientY - shiftY + 'px';
    }
})

document.addEventListener("mouseup",ev =>{
    if(dragging){
        draggedObject.style.position = 'static'
        let placeholder = document.querySelector("#placeholder");
        container.removeChild(placeholder);
        dragging = false
    }
})
代码语言:javascript
复制
/* the :not(:last-of-type(div)) is there so the console doesn't get affected */
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    background-color: black;
}
.draggable {
    width: 90px;
    height: 120px;
    margin: 5px;
}


#placeholder {
    width: 90px;
    height: 120px;
    margin: 5px;
    background-color: rgba(0, 0, 0, 0.3);
    border: dashed grey 5px;
}
代码语言:javascript
复制
<body draggable="false" ondragstart="return false;">
<div id = "big-container" style ="display: flex; background-color: rgb(76, 104, 95); width: 500px; height: 500px;">
    <div style="background-color: rgb(204, 125, 111);" class="draggable"></div>
    <div style="background-color: rgb(170, 214, 120);" class="draggable"></div>
    <div style="background-color: rgb(129, 212, 167);" class="draggable"></div>
    <div style="background-color: rgb(162, 137, 196);" class="draggable"></div>
</div>
</body>

我试图实现的是,在鼠标按下时,元素应该停留在原来的位置,之后当我移动鼠标移动元素时,元素也应该保持在原来的位置。(锚点应该在我单击元素的位置)。我之所以执行shiftX = ev.offsetX+5;,是因为我需要考虑元素的边距。

问题是,当我单击一个元素(并且根本不移动我的鼠标)时,您可以看到该元素的位置发生了一点变化。它非常小(可能是1或2px),并且不是在所有地方都会发生(元素中的一些区域不会引入这种位置移动)。

你们知道可能是什么引起的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-16 08:47:14

您可以使用getBoundingClientRect()来获取实际位置。

代码语言:javascript
复制
let container = document.querySelector("#big-container");
var dragging = false;
var draggedObject;
let shiftX = 0;
let shiftY = 0;
document.querySelectorAll(".draggable").forEach((draggable, index) => {
  draggable.style.order = index;
  draggable.draggable = false;
  draggable.ondragstart = () => {
    return false;
  };
  draggable.addEventListener("mousedown", (ev) => {
    draggedObject = draggable;
    var x = draggable.getBoundingClientRect().top - 5;
    var y = draggable.getBoundingClientRect().left - 5;
    shiftX = ev.offsetX + 5;
    shiftY = ev.offsetY + 5;
    draggable.style.position = "absolute";
    draggable.style.left = y + "px";
    draggable.style.top = x + "px";
    dragging = true;
    let placeholder = document.createElement("div");
    placeholder.id = "placeholder";
    placeholder.style.order = draggable.style.order;
    container.appendChild(placeholder);
  });
});

document.addEventListener("mousemove", (ev) => {
  if (dragging) {
    draggedObject.style.left = ev.clientX - shiftX + "px";
    draggedObject.style.top = ev.clientY - shiftY + "px";
  }
});

document.addEventListener("mouseup", (ev) => {
  if (dragging) {
    draggedObject.style.position = "static";
    let placeholder = document.querySelector("#placeholder");
    container.removeChild(placeholder);
    dragging = false;
  }
});
代码语言:javascript
复制
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  background-color: black;
}
#big-container {
  width: 500px;
  height: 500px;
}
.draggable {
  width: 90px;
  height: 120px;
  margin: 5px;
}

#placeholder {
  width: 90px;
  height: 120px;
  margin: 5px;
  background-color: rgba(0, 0, 0, 0.3);
  border: dashed grey 5px;
}
代码语言:javascript
复制
<body draggable="false" ondragstart="return false;">
    <div
      id="big-container"
      style="display: flex; background-color: rgb(76, 104, 95);"
    >
      <div
        style="background-color: rgb(204, 125, 111);"
        class="draggable"
      ></div>
      <div
        style="background-color: rgb(170, 214, 120);"
        class="draggable"
      ></div>
      <div
        style="background-color: rgb(129, 212, 167);"
        class="draggable"
      ></div>
      <div
        style="background-color: rgb(162, 137, 196);"
        class="draggable"
      ></div>
    </div>

  </body>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67116519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档