2017-06-23 42 views
3

我正在嘗試使用拖放操作將圖片從一個<div>移動到另一個。在JavaScript中捕捉拖放項目

目前,我可以將圖片移動到目的地<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); 
 
} \t
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; 
 
}
<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"> \t 
 
</div> 
 

 
<div id="div4"> 
 
    <div align="center" id="imgDiv" ondrop="dropClone(event)" ondragover="allowDrop(event)"></div> 
 
</div>

回答

1

當你開始拖動圖像,你需要存儲的光標相對於特定圖像的位置。

MouseEvent有多個位置屬性可以幫助您計算,但如果瀏覽器支持不是問題,我會去MouseEvent.offsetXMouseEvent.offsetY。從該文檔:

offsetX/offsetY只讀提供在X/Y的偏移事件和目標節點的填充邊緣之間的鼠標指針的座標的MouseEvent接口的屬性。

因此,在dragstart,你會做的只是:

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

然後,當你把你的形象,讓我們把它帆布(注意斜體字,因爲它不是一個<canvas>元素,但是任何其他用作放置區域的元素(在此特定示例中爲<div>)),則需要知道光標相對於該畫布的位置,因此您可能認爲可以再次使用offsetXoffsetY,並且您的部分正確。如果您將圖像放在畫布本身上,但是其中可能還有其他圖像,並且您可能會將當前圖像放在另一個圖像上,則會得到期望的值,相對於此,可以獲得offsetXoffsetY一個代替。

你可以做的是使用MouseEvent.pageXMouseEvent.pageY,並從該值,減去(左上角)的那帆布元素,你可以從HTMLElement.offsetLeftHTMLElement.offsetTop得到的位置:

e.pageX - imageCanvas.offsetLeft; 
e.pageY - imageCanvas.offsetTop; 

使用此功能,您將獲得光標相對於畫布元素的位置。

現在,你需要減去你存儲在dragstartxy價值觀,這將會給你拖圖像的左上角,相對於帆布元素的lefttop值:

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; 
 
}
<div id="imagesBar"> 
 
    <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/18/Bartagame_fcm.jpg/1200px-Bartagame_fcm.jpg" draggable="true"> 
 
    <img src="http://www.earthtimes.org/newsimage/lizard_Ngo_Van_Tri_big_281.jpg" draggable="true"> \t 
 
</div> 
 

 
<div id="imagesCanvas"></div>

+0

這根本不適用於我。 :/ – Yikes

+0

@Yikes哪部分工作不正確?你的意思是_snap together_你只是想讓圖像並排排列,而不是將它們自由地移動到任意位置? – Danziger

+0

不,你完全理解我想要它做什麼(並感謝你花時間寫出所有這些)!無論什麼原因,當我嘗試運行這段代碼時,甚至沒有正常的下降。圖像只會反彈回原來的位置。我甚至無法測試將它們拼湊在一起的部分。 – Yikes