Reputation: 344
What I wanted: a div "dragItem" should be moved horizontally. If the mouse cursor is on top of a div with the class "tag", then the position of "dragItem" will be changed.
Actually this is working. But I got a strange behavior, when I release my mouse button while the cursor is not in the same horizontal row as where it started moving: next time I click on "dragItem" I can't see the movement until I relaese the mouse button. AND: after I released the mouse button, I am still able to move "dragItem" around.
I don't understand why this happens. While trying to debug it, I found out, that - if I click somewhere on the screen before clicking on "dragItem" - things work as expected. But why?
dragItem = document.getElementById("dragItem")
dragItem.addEventListener('mousedown', dragMouseDownHandler)
mouseIsDown = false;
function dragMouseDownHandler(event) {
if (!mouseIsDown) {
mouseIsDown = true;
document.addEventListener('mousemove', mouseMove)
document.addEventListener('mouseup', mouseUp)
}
}
function mouseMove(event) {
var elementsUnderMouse = document.elementsFromPoint(event.clientX, event.clientY);
elementsUnderMouse.forEach(element => {
if (element.classList.contains("tag")) {
vonLinks = element.offsetLeft
dragItem.style.left = vonLinks + 'px'
}
})
}
function mouseUp(event) {
mouseIsDown = false;
document.removeEventListener('mousemove', mouseMove)
document.removeEventListener('mouseup', mouseUp)
}
#moveArea {
width: 600px;
height: 600px;
background-color: lightgray;
display: flex;
flex-direction: column;
}
.row {
display: flex;
flex-direction: row;
}
.tag {
height: 110px;
width: 110px;
background-color: #b3d4fc;
border: 1px solid black;
}
#dragItem {
height: 100px;
width: 100px;
background-color: lightcoral;
position: fixed;
}
<div id="moveArea">
<div class="row">
<div class="tag">
<div id="dragItem"></div>
</div>
<div class="tag"></div>
<div class="tag"></div>
<div class="tag"></div>
</div>
<div class="row">
<div class="tag"></div>
<div class="tag"></div>
<div class="tag"></div>
<div class="tag"></div>
</div>
</div>
Upvotes: 1
Views: 58
Reputation: 1
Maybe you'd be better of using the more modern Drag & Drop API to implement such mechanic.
This also:
mouseup
behaviorMaybe you'd also want to actually move the element in DOM rather than shifting it's position visually. This way the visual and logical appearance would be aligned and processable by JS.
The attached snippet shows a crude implementation using drag & drop.
const dragItem = document.getElementById('dragItem');
const dropTargets = document.querySelectorAll('.tag');
makeMoveableTo(dragItem, ...dropTargets);
/**
* Makes the `element` moveable (drag & drop) to the `targetElements`.
* @param {HTMLElement} element
* @param {...HTMLElement} targetElements
*/
function makeMoveableTo( element, ...targetElements )
{
element.addEventListener('dragstart', ( event ) =>
{
// Remember the id of the element to drag on dragstart
event.dataTransfer.setData('text/plain', event.target.id);
});
targetElements.forEach(targetElement =>
{
targetElement.addEventListener('dragover', ( event ) =>
{
// Mark target as drop-zone
event.preventDefault();
event.dataTransfer.dropEffect = 'move';
});
targetElement.addEventListener('drop', ( event ) =>
{
// On drop, read the dragged element's id and call moveTo()
const dragElementId = event.dataTransfer.getData('text/plain');
const dragElement = document.getElementById(dragElementId);
moveTo(dragElement, event.target);
});
});
}
/**
* Moves the `element` to the `targetElement`.
* @param {HTMLElement} element
* @param {HTMLElement} targetElement
*/
function moveTo( element, targetElement )
{
element.style.left = `${targetElement.offsetLeft}px`;
// targetElement.append(element); // Maybe move element in DOM instead
}
#moveArea{
width: 600px;
height: 600px;
background-color: lightgray;
display: flex;
flex-direction: column;
}
.row{
display: flex;
flex-direction: row;
}
.tag{
height: 110px;
width: 110px;
background-color: #b3d4fc;
border: 1px solid black;
}
#dragItem{
height: 100px;
width: 100px;
background-color: lightcoral;
position: fixed;
}
<div id="moveArea">
<div class="row">
<div class="tag">
<div id="dragItem" draggable="true"></div>
</div>
<div class="tag"></div>
<div class="tag"></div>
<div class="tag"></div>
</div>
<div class="row">
<div class="tag"></div>
<div class="tag"></div>
<div class="tag"></div>
<div class="tag"></div>
</div>
</div>
Upvotes: 0