Search code examples
typescriptdom-eventssvelteonmouseoveroverlapping

Check if mouse is over div element, even if overlapped


I'm making a chess game using svelte and ts, and I want to detect which square the mouse is over, so it can be the targetSquare of the currently dragged piece. In other word, I say: if square is hovered, then set targetPosition to its position. However, The onmouseenter event is not fired for squares that are under a Piece element. (because the piece is completely overlapping the square). How do you fire the onmouseenter event for these squares? (I don't want to use "pointer-events: none" for the chess piece because I need the drag events for it) The piece and square components are divs.

// in the Square svelte component

square.onmouseenter = () => {
PieceLogic.hoveredSqr = index;
}

// in the Piece svelte component
piece.onmouseup = () => {
setPosition(PieceLogic.hoveredSqr);
}

Solution

  • Mouse over events are not fired during drag at all. You will have to use drag-specific events like dragenter and dragleave.

    I would recommend just disabling pointer events during the drag only. If the piece is within the tile hierarchically, this could be done by just setting a class on the tile on dragenter. If they are not hierarchically related, you will have to communicate that in code.

    A simple example where the hierarchy exists:

    <script>
        let hovered = false;
    </script>
    <div class="tile" class:hovered
         on:dragenter={() => hovered = true}
         on:dragleave={() => hovered = false}>
        <div class="piece" draggable="true" />
    </div>
    
    <style>
        .tile.hovered .piece { pointer-events: none; }
    </style>
    

    REPL

    (If you are not using the drag & drop API, the same approach of disabling the pointer events conditionally should work as well.)