在JavaScript中捕捉拖放项目

时间:2017-06-23 21:51:45

标签: javascript html css html5 drag-and-drop

我正在尝试使用拖放功能将图片从一个<div>移动到另一个<div>

目前,我可以将图片移动到目的地<canvas>中的任何位置,但我真正想要的是图片在放下时会卡在一起。理想情况下,它们可以在任何一侧(不仅仅是在底部或右侧)拼接在一起。

我尝试了一些不同的事情(包括使用var clone; var offsetx = null; var offsety = null; var isClone = false; function allowDrop(ev) { ev.preventDefault(); } function drag(ev) { offsetx = ev.target.offsetLeft - event.clientX; offsety = ev.target.offsetTop - event.clientY; ev.dataTransfer.setData("text", ev.target.id); } function dropTrash(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("text"); var remove = document.getElementById(data); remove.parentNode.removeChild(remove); } function drop(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("text"); } function dropClone(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("text"); var num = Math.random() * (1000 - 1) + 1; isClone = true; clone = document.getElementById(data).cloneNode(true); clone.id = "newId" + num.toString(); clone.style.position = "absolute"; clone.style.left = (event.clientX+offsetx)+"px"; clone.style.top = (event.clientY+offsety)+"px"; ev.target.appendChild(clone); } )但它没有用。

这是我到目前为止所做的:

&#13;
&#13;
html, body { 
  height: 100%; 
  padding: 0; 
  margin: 0; 
}

div { 
  width: 50%; 
  height: 50%; 
  float: left; 
}

#div1 { 
  background: #DDD; 
}

#div2 {
  background: #AAA; 
}

#div3 {
  background: #777; 
}

#div4 { 
  background: #444; 
}

#imgDiv {
  width: 611px;
  height: 324px;
  border: 5px solid #DDD;
}
&#13;
<div id="div1">
</div>

<div id="div2">
</div>

<div id="div3" ondrop="dropTrash(event)" ondragover="allowDrop(event)">
  <img  id="drag1" src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Bartagame_fcm.jpg/1200px-Bartagame_fcm.jpg" draggable="true" ondragstart="drag(event)" width="105" height="105">
  <img  id="drag2" src="http://www.earthtimes.org/newsimage/lizard_Ngo_Van_Tri_big_281.jpg" draggable="true" ondragstart="drag(event)" width="105" height="105">	
</div>

<div id="div4">
  <div align="center" id="imgDiv" ondrop="dropClone(event)" ondragover="allowDrop(event)"></div>
</div>
&#13;
$('#PatientID').change(onPatientChange);

function onPatientChange(eventData) {
    console.log($(this).val());
    // Ajax call should be placed here, and when the data is received
    // you should replace it with the old text boxes.
    // using $('#DoB').val(VALUE-RETURNED-BY-SERVER);
}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

开始拖动图像时,需要存储光标相对于特定图像的位置。

MouseEvent中有多个位置属性可以帮助您计算,但如果浏览器支持不是问题,我会选择MouseEvent.offsetXMouseEvent.offsetY。来自文档:

  

MouseEvent接口的offsetX / offsetY只读属性提供了该事件与填充之间鼠标指针的X / Y坐标的偏移量目标节点的边缘。

所以,在dragstart上,你会做到:

x = e.offsetX;
y = e.offsetY;

然后,当你将图像放入你的图像时,我们将其称为 canvas (注意斜体,因为它不是<canvas>元素,而是用作你的drop的任何其他元素区域,在此特定示例中为<div>,您需要知道光标相对于该画布的位置,因此您可能认为可以再次使用offsetXoffsetY,并且部分正确。如果您将图像放在画布本身上,这会给您预期的值,但是其中可能还有其他图像,您可以将当前的图像放在另一个图像的顶部,获取{相对于那个而言{1}}和offsetX

您可以使用MouseEvent.pageXMouseEvent.pageY,并从该值中减去该画布元素的(左上角)位置,您可以从HTMLElement.offsetLeftHTMLElement.offsetTop获取

offsetY

使用此功能,您将获得光标相对于 canvas 元素的位置。

现在,您需要减去e.pageX - imageCanvas.offsetLeft; e.pageY - imageCanvas.offsetTop; 上存储的xy值,这将为您提供dragstartleft值相对于 canvas 元素,拖动图像的左上角:

top

所有这些看起来都像这样:

image.style.left = (e.pageX - imagesCanvas.offsetLeft - x) + 'px';
image.style.top = (e.pageY - imagesCanvas.offsetTop - y) + 'px';
let x;
let y;
let currentTarget = null;
let cloneElement = false;

function startDrag(e, clone) {
  const target = e.target;
  
  if (target.tagName === 'IMG') {
    x = e.offsetX;
    y = e.offsetY;
    currentTarget = target;
    cloneElement = clone;
  }
}

function cloneImage(e) {
  startDrag(e, true);
}

function moveImage(e) {
  startDrag(e, false);
}

function removeImage(e) { 
  if (!cloneElement) {
    currentTarget.remove();
  }
}

function stickImage(e) { 
  const image = cloneElement ? currentTarget.cloneNode(true) : currentTarget;
  
  imagesCanvas.appendChild(image);
  
  // + 1 for the border
  
  image.style.left = (e.pageX - imagesCanvas.offsetLeft - x + 1) + 'px';
  image.style.top = (e.pageY - imagesCanvas.offsetTop - y + 1) + 'px';
  
  currentTarget = null;
}

function allowDrag(e) {
  e.preventDefault();
}

// Bind event listeners:

const imagesBarElement = document.getElementById('imagesBar');
const imagesCanvasElement = document.getElementById('imagesCanvas');

document.addEventListener('dragenter', allowDrag);
document.addEventListener('dragover', allowDrag);

imagesBarElement.addEventListener('dragstart', cloneImage);
imagesBarElement.addEventListener('drop', removeImage);

imagesCanvasElement.addEventListener('dragstart', moveImage);
imagesCanvasElement.addEventListener('drop', stickImage);
body {
  margin: 0;
  font-size: 0;
  display: flex;
  flex-direction: column;
  height: 100vh;
  user-select: none;
}

img {
  width: 100px;
  height: 100px;
}

#imagesBar {
  height: 100px;
  border-bottom: 1px solid #CCC;
  padding: 10px 0;
}

#imagesBar > img {
  margin: 0 0 0 10px;
}

#imagesCanvas {
  position: relative;
  background: #EEE;
  flex-grow: 1;
  overflow: hidden;
}

#imagesCanvas > img {
  position: absolute;
}