kadina
kadina

Reputation: 5372

How to prevent mouseenter/mouseleave events getting fired for Canvas if a button is on top of canvas and if mouse enters the button

We are implementing Video Call application. And user should be able to draw on the video using mouse and when mouse enters the remote video, we need to display a button on the video (to disconnect the call when user clicks the button) and when mouse exits the video, the button needs to be removed.

For this, we are creating below elements dynamically in javascript

  1. Video Element - to display the video
  2. Canvas - transparent canvas exactly on top of video element with same dimensions as video (So user can draw on video)
  3. Button - Dynamically creating button for 'mouseenter' event of canvas and removing the button for 'mouseleave' event of canvas.

The order will be like this. Video -> Canvas on top of Video -> Button on top of Canvas when mouse enters canvas.

Displaying of button when mouse enters Canvas and removing the button when mouse leaves canvas is working fine. But I am facing below issues.

  1. When I move mouse on top of button, 'mouseleave' event is being fired for Canvas and when I move mouse outside of button, 'mouseenter' event is being fired for Canvas. Because of this when I move mouse on button, the button is getting deleted and removed continuously (This is because when I move mouse on button, mouseleave event is fired and in mouseleave event handler, I am deleting button. Now as the button is removed, and canvas is under, mouseenter event is getting fired and I am adding button in mouseenter event handler).

Below is the code.

remoteVideo = document.createElement('video');
remoteVideo.setAttribute("id", "remoteVideo");
remoteVideos.appendChild(remoteVideo);
localCanvas = document.createElement('canvas');
localCanvas.setAttribute("id", "localCanvas");
remoteVideos.appendChild(localCanvas);

    $("#remoteVideo").on("loadedmetadata", () => {
        const remoteVideoEle = document.getElementById('remoteVideo');
        const localCanvasEle = document.getElementById('localCanvas');

        localCanvasEle.setAttribute('width', remoteVideoEle.offsetWidth);
        localCanvasEle.setAttribute('height', remoteVideoEle.offsetHeight);
        localCanvasEle.style.position = 'absolute';
        localCanvasEle.style.background = 'transparent';

        $('#localCanvas').on('mouseenter', (e) => {
           // DISPLAYING BUTTON HERE
           if(termBtn === undefined) {
               termBtn = document.createElement('button');
               termBtn.style.left = localCanvas.getBoundingClientRect().x + (localCanvas.getBoundingClientRect().width / 2) - 25 + 'px';
               termBtn.style.top = localCanvas.getBoundingClientRect().y + localCanvas.getBoundingClientRect().height - 65 + 'px';
               termBtn.classList.add("terminate_session_btn");
               remoteVideos.appendChild(termBtn);
           } else {
               $(".terminate_session_btn").show();
           }
        });

        $('#localCanvas').on('mouseleave', (e) => {
            console.log("mouse exited remote video");
            $(".terminate_session_btn").remove();
            termBtn = undefined;
        });
    });

I don't want the mouseenter and mouseleave events generated for Canvas when mouse is over the button (technically part of canvas is just under the button so these events shouldn't be fired) because the drawing functionality depends on mouseleave event of canvas.

Can some one please help me how to prevent mouse enter/leave events getting fired when mouse enters button.

Adding

'pointer-events: none;' 

to the button achieves the behavior described, but click event is not being fired when I click the button.

Upvotes: 2

Views: 1248

Answers (2)

Lajos Arpad
Lajos Arpad

Reputation: 76988

You do not necessarily need to avoid those events being fired. You can use a flag for mouseenter:

    $('#localCanvas').on('mouseenter', (e) => {
        if (!buttonHovered) {
            //Your code
        }
        buttonHovered = false;
        canvasHovered = true;
    });

Of course you need to initialize those flags with false. The hover on button should set buttonHovered to true. Now, if the canvas is surrounded by a tag, then, instead of a mouseleave on the canvas you can define a mouseenter for its surrounding tag and check for the value of canvasHovered at the start and set canvasHovered to false at the end.

Upvotes: 1

kadina
kadina

Reputation: 5372

Adding 'pointer-events: none;' to the button solved the problem. But click event is not being fired when I click the button.

Upvotes: 1

Related Questions