Search code examples
javascriptdrag-and-dropdraggable

Detect container, while moving an element over it


I making a simple drag'n'drop interface. I have a bunch of containers ("wrapper") and some dynamically added items ("dragElement") in one of them. So I need, when I move item over another container, JS detect it and move the item there when the drag is finished.

I tried to detect container with "onmouseover" and "mouseup" when dragging item, but had no success, because, actually, mouse always was over the dragged element. So how can I detect container when drag item? In pure JS please...

document.onmousedown = function(e) {

    var dragElement = e.target;

    if (!dragElement.classList.contains('draggable')) return;

    var coords, shiftX, shiftY, detectPage;

    startDrag(e.clientX, e.clientY);

    document.onmousemove = function(e) {
        moveAt(e.clientX, e.clientY);
    };

    wrapper.onmouseover = function(e) {
        detectPage = e.target;
        console.log(detectPage);
    };

    dragElement.onmouseup = function() {
        finishDrag();
    };

    function startDrag(clientX, clientY) {

        shiftX = clientX - dragElement.getBoundingClientRect().left;
        shiftY = clientY - dragElement.getBoundingClientRect().top;

        dragElement.style.position = 'fixed';

        document.body.appendChild(dragElement);

        moveAt(clientX, clientY);

    };

    function finishDrag() {

        dragElement.style.top = parseInt(dragElement.style.top) - wrapper.getBoundingClientRect().top + 'px';
        dragElement.style.position = 'absolute';

        wrapper.onmouseup = function(e) {
            var selectPage = e.target;
        }

        wrapper.appendChild(dragElement);

        document.onmousemove = null;
        dragElement.onmouseup = null;

    };

    function moveAt(clientX, clientY) {
        var newX = clientX - shiftX;
        var newY = clientY - shiftY;

        if (newX < 0) newX = 0;
        if (newX > wrapper.offsetWidth - dragElement.offsetWidth) {
            newX = wrapper.offsetWidth - dragElement.offsetWidth;
        }

        dragElement.style.left = newX + 'px';
        dragElement.style.top = newY + 'px';
    };

    return false;
};

Solution

  • Well, no one help. So one free day gone to find the solution. All I can found is to delete function finishDrag() from dragElement.onmouseup and change it to the code below.

    If in shorter, when onmouseup comes, dragElement must go to display:none and now we can get access to the object near the mouse cursor through elementFromPoint. When we done with it, we can easily detects container, bring an element back to display:block and put it to that container...

    Hope, it helps to someone...

        dragElement.onmouseup = function(e) {
    
            dragElement.style.display = 'none';
    
            var selectPage = document.elementFromPoint(e.clientX, e.clientY);
    
            dragElement.style.display = 'block';
    
            dragElement.style.top = parseInt(dragElement.style.top) - selectPage.getBoundingClientRect().top + 'px';
            dragElement.style.position = 'absolute';
    
            selectPage.appendChild(dragElement);
    
            document.onmousemove = null;
            dragElement.onmouseup = null;
    
        };