如何使可拖动元素在拖放时保持在新位置(HTML5 不是 jQuery)?

Posted

技术标签:

【中文标题】如何使可拖动元素在拖放时保持在新位置(HTML5 不是 jQuery)?【英文标题】:How to make a draggable element stay at the new position when dropped (HTML5 not jQuery)? 【发布时间】:2019-12-17 12:30:40 【问题描述】:

我刚刚学习了 html5 可拖放 API 的基础知识。我不知道如何将拖动位置保留在其放置位置。放下它会改变它的位置。

这是基本的 HTML(仅相关元素):

onDragStart = function(ev) 
  //...


drop_handler = function(ev) 
  ev.preventDefault();
  ev.target.appendChild(document.getElementById("id1"));


dragover_handler = function(ev) 
  ev.preventDefault();
  ev.dataTransfer.dropEffect = "move";
<div id="id1" draggable="true" ondragstart="onDragStart(event)" style="border:2px solid green; cursor:pointer;width:100px;height:50px;">Dragged Div</div>


<div id="id2" style="position:absolute;left:100px;top:200px;border:2px solid red; cursor:pointer;width:200px;height:200px;" ondrop="drop_handler(event)" ondragover="dragover_handler(event)">Drop Div
</div>

我希望被拖动的元素保持在它被放置的最终位置。任何指针将不胜感激。

【问题讨论】:

你应该避免在style标签中放太多东西,而是使用css类 如果您希望元素准确地出现在它被放置的位置,您需要在放置元素内使用绝对或相对定位。它正在改变它的位置,因为它仍然是position: static(默认值),这是浏览器的正常流程...... div 只是在已经存在的文本内容下方。如果您仍然需要这方面的帮助,我可以稍后再写一个正确的答案。 【参考方案1】:

正如我在评论中提到的,&lt;div id="id1" ...&gt; 仍然具有默认定位,即static。将其附加到 dropDiv 后,它会采用正常的文档流行为。因为它是块元素,所以它位于已经存在的文本下方并填充块的宽度。

如果你想让它在你放下它时保持在原来的位置,你需要给它position: absolute 并考虑鼠标在屏幕上拖动时的移动方式。在dragStart 事件中,我们捕获了dragDiv 的原始坐标,并说明了鼠标相对于左上角的内部位置。当我们将 dragDiv 放到 dropDiv 中时,我们设置了绝对定位并考虑了鼠标在拖动过程中移动了多少。

由于 dragDiv 现在是 dropDiv 的子项,我们需要新的 top 和 left 值相对于 dropDiv 的坐标而不是整个屏幕,因此我们减去 dropDiv 的 top 和 left 值。请注意,其中一些方法可能没有考虑到元素周围的边界,这可能使它看起来像一个或两个像素 - 要解决这个问题,您可以在计算中减去一个或两个像素或给它们@ 987654325@.

let offsetX;
let offsetY;

onDragStart = function(ev) 
  const rect = ev.target.getBoundingClientRect();

  offsetX = ev.clientX - rect.x;
  offsetY = ev.clientY - rect.y;
;

drop_handler = function(ev) 
  ev.preventDefault();

  const left = parseInt(id2.style.left);
  const top = parseInt(id2.style.top);

  id1.style.position = 'absolute';
  id1.style.left = ev.clientX - left - offsetX + 'px';
  id1.style.top = ev.clientY - top - offsetY + 'px';
  id2.appendChild(document.getElementById("id1"));
;

dragover_handler = function(ev) 
  ev.preventDefault();
  ev.dataTransfer.dropEffect = "move";
;
<div id="id1" draggable="true" ondragstart="onDragStart(event)" style="border:2px solid green; cursor:pointer;width:100px;height:50px;">Dragged Div</div>


<div id="id2" style="position:absolute;left:200px;top:50px;border:2px solid red; cursor:pointer;width:200px;height:200px;" ondrop="drop_handler(event)" ondragover="dragover_handler(event)">Drop Div
</div>

【讨论】:

以上是关于如何使可拖动元素在拖放时保持在新位置(HTML5 不是 jQuery)?的主要内容,如果未能解决你的问题,请参考以下文章

Jquery ui div在拖放时不可拖动

如何阻止 QTreeWidget 在拖放时创建重复项

jQuery拖放 - 如何获取被拖动的元素

C#在拖放时实现ListView中的自动滚动

使用 HTML5 原生拖放时如何约束移动?

为什么我的图像在拖放时会在我的AnchorPane中重新定位?