Mouseleave triggered by click

Viewed 9583

I have an absolutely-positioned div, and I'm trying to keep track of when the mouse moves over it, and when the mouse leaves. Unfortunately clicking on the text in the box occasionally triggers the mouseleave event.

DEMO: js fiddle

How can I prevent this?

JS

let tooltip = document.createElement('div');
tooltip.innerHTML = 'HELLO WORLD';
tooltip.setAttribute('class', 'tooltip');
tooltip.style.display = 'none';

tooltip.onclick = evt => {
    console.log('click')
    evt.stopPropagation();
}
tooltip.ondblclick = evt => {
    console.log('double click')
    evt.stopPropagation();
}

tooltip.onmouseenter = () => {
    console.log('tooltip mouse OVER');
}

tooltip.onmouseleave = () => {
    console.log('tooltip mouse OUT')
}

tooltip.style.left = '290px';
tooltip.style.top = '50px';
tooltip.style.display = 'block';
document.body.appendChild(tooltip);

HTML

<div style="width: 300px; height: 300px; background-color: lightblue">

</div>

CSS

.tooltip {
    position: absolute;
    /*display: none;*/
    left: 100;
    top: 100;
    min-width: 80px;
    height: auto;
    background: none repeat scroll 0 0 #ffffff;
    border: 1px solid #6F257F;
    padding: 14px;
    text-align: center;
}
6 Answers

The answer by @trincot almost worked for me. In my case I'm dealing with popovers. When I click on a button, it triggers a popover showing up on top of the triggering button. So document.elementFromPoint(e.clientX, e.clientY) returns the popover element rather than the triggering button. Here's how I solved this:

mouseleave(ev: MouseEvent) {
    const trigger: HTMLElement = document.getElementById('#myTrigger');
    const triggerRect = trigger.getBoundingClientRect();
    const falsePositive = isWithingARect(ev.clientX, ev.clientY, triggerRect);

    if (!falsePositive) {
        // do what needs to be done
    }
}

function isWithingARect(x: number, y: number, rect: ClientRect) {
  const xIsWithin = x > rect.left && x < rect.right;
  const yIsWithin = y > rect.top && y < rect.bottom;
  return xIsWithin && yIsWithin;
}

Check if the primary button is pressed with MouseEvent.buttons.

tooltip.onmouseleave = (e) => {
  if (e.buttons !== 1) {
    console.log('tooltip mouse OUT')
  }
}
Related