Search code examples
javascriptpointer-events

How can I detect an element underneath an image that I am dragging within a Pointer Event?


I have dynamically created a chess board using JavaScript with all the pieces in their starting squares. I have worked out how to get the pieces to move around on the board but cannot figure out how to detect the square(a paragraph element) under which the piece I am dragging around on the board(an image element). I am using Pointer Events and am pretty sure I need to append the image I am dragging to the square I am dropping it on.

let pieces = document.getElementsByTagName('img');


board.addEventListener('pointerdown', (e) =>  {
    e.target.ondragstart = () => {
      return false;
    };
    if(e.target.className.includes('square')){
        return false
    }
    
    
    board.addEventListener('pointerup', removeDots)
    board.addEventListener('pointermove', movePiece)
    //board.addEventListener('pointerover', dropZone)
});

function removeDots(e) {
    console.log(e.target.parentElement)
    board.removeEventListener('pointermove', movePiece)
    board.removeEventListener('pointerup', removeDots)
    
}

function movePiece(e){
    e.target.style.position = 'fixed';
    e.target.style.left = e.pageX - e.target.offsetWidth / 2 + 'px';
    e.target.style.top = e.pageY - e.target.offsetHeight / 2 + 'px';
    

}

This portion is what I am using to get the only the pieces moving and not the whole board. Feel free to let me know if there is an error here.

    e.target.hidden = true; 
    let elemBelow = document.elementFromPoint(e.clientX, e.clientY);
    let droppableBelow = elemBelow.closest('p');
    console.log(droppableBelow)
    e.target.hidden = false;

I found this on a website and tried implementing it into my code but the droppableBelow only ever returns the original element from where I picked it up from. Even when I drag it to a new square, drop it and pick it back up. I am just using plain old JS and have no experience(yet) with Jquery, although I did look for solutions there too. Everything I found(if I was looking in the correct spot) had to do with just mouse events. (I am also aware of chessboard.js but wish to create my own for the experience)

For visual reference of my Chess Board


Solution

  • Instead of using elementFromPoint(), I found my answer in elementsFromPoint():

    function dropPiece(e) {
        let clone = e.target.cloneNode(true);
        clone.style.position = 'inherit';
        let position = document.elementsFromPoint(e.clientX, e.clientY);
        position[1].appendChild(clone);
        e.target.remove();
        board.removeEventListener('pointermove', movePiece);
        board.removeEventListener('pointerup', dropPiece);
    }
    

    Instead of returning the most nested element, it gives an array of all elements from the given coordinates.