鼠标点击触发鼠标离开

Posted

技术标签:

【中文标题】鼠标点击触发鼠标离开【英文标题】:Mouseleave triggered by click 【发布时间】:2017-12-29 05:29:23 【问题描述】:

我有一个绝对定位的 div,我试图跟踪鼠标何时移过它,以及鼠标何时离开。不幸的是,单击框中的文本偶尔会触发 mouseleave 事件。

演示:js fiddle

如何防止这种情况发生?

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;

【问题讨论】:

对我来说很好:i.imgur.com/zFA9KXI.gifv 您正在尝试哪种浏览器?这在 Mozilla 和 chrome 中完美运行。 检查扩展等 Chrome - 在字符周围单击时很少发生。似乎与光标变化不谋而合。 我保证这不是什么玩笑——我知道复制品可能很少见。我在 Chrome 最新的稳定版(不是金丝雀)上。如果有人知道这可能发生的原因以及如何预防,我很想听听。 【参考方案1】:

用MouseEvent.buttons检查主按钮是否被按下。

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

【讨论】:

【参考方案2】:

@trincot 的回答几乎对我有用。就我而言,我正在处理弹出窗口。当我点击一个按钮时,它会触发一个弹出窗口,显示在触发按钮的顶部。所以document.elementFromPoint(e.clientX, e.clientY) 返回的是弹出框元素而不是触发按钮。这是我解决这个问题的方法:

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;

【讨论】:

【参考方案3】:
var trackmouseup = null;

$('.box').mouseup(function(event)
    if(trackmouseup)
        clearTimeout(trackmouseup);
    
    trackmouseup = setTimeout(function()
        trackmouseup = null;
    , 2); //it must be 2ms or more

);


$('.box').mouseleave(function(event)
    //if this event is triggered by click, there must be a mouse up event triggered 2ms ago
    if(trackmouseup)
        return;
    

    //to do something
);

【讨论】:

【参考方案4】:

我之前在这里查看了答案和cmets,但最近找到了一种方法来检查mouseleave事件是否被错误触发

我在mouseleave 处理程序中添加了一个检查:

private handleMouseLeave(event: MouseEvent) 
    if(event.relatedTarget || event.toElement)
        // do whatever
    
    // otherwise ignore

根据我在 Chrome v64 上的测试,只要快速点击导致触发 mouseleave 事件,这两个值都会是 nullrelatedTarget 是为了与旧版浏览器兼容

注意:如果鼠标离开 target 元素并进入浏览器(例如选项卡、菜单等)或离开浏览器窗口,这两个值也将是 null。出于我的目的,这不是问题,因为它是我正在使用的滑动菜单,在我的特定情况下,离开浏览器窗口不应关闭菜单。

注意:每次点击我的菜单时,最新的 Firefox 版本(2018 年 2 月)似乎都会触发 mouseleave!一定要调查一下

【讨论】:

好发现 - 一定要花很长时间才能找到:) @T4NK3R 是的,花了整个星期六晚上比较不同事件的 MouseEvent 属性!!!感谢您的评论,很高兴在所有调试后得到一些反馈:-) 不客气 - 让我不必在我的游戏中添加 jQuery :) - 顺便说一句:在我的 Firefox (61.0.2) 中没有看到任何有趣的事情..【参考方案5】:

我也遇到了这个错误。就我而言,我将标签包装的复选框添加到列表中,并将列表包装在 div 中。我还使用了一些&lt;hr&gt; 标签的列表项。如果您快速单击复选框和标签,您偶尔会在包装 div 上触发 mouseleave 事件。这不应该发生,因为所有单击的元素都是 div.wrapper 的子元素。

...
  wrapper.addEventListener(
    'mouseleave',
    (e) => 
      logger('mouseleave fired');
      console.log('mouseleave fired', e);
    ,
    false
  );
...

jsfiddle demo

这是复制的 gif。在线索区域内点击(授予一定强度和移动),标签和输入框的点击事件被触发,然后你会看到两个 mouseleave 事件错误触发,然后当鼠标真正触发时第三个离开蓝色区域。

【讨论】:

这不是问题的答案。如果这个问题的其他答案不能解决您的问题,那么您可以提出一个新问题。一旦您有足够的声誉,您还可以对原始帖子发表评论,提供您对这个明显错误的体验。 感谢您发布此信息。这是一个答案,因为它表明它是一个错误。我刚刚花了一个小时试图弄清楚为什么会发生这种情况!【参考方案6】:

这似乎是一个错误(我可以在 Chrome 中重现它,单击鼠标向下和鼠标向上依次快速发生)。

我建议通过检查事件触发时鼠标是否仍在元素上方来解决此问题:

tooltip.onmouseleave = (e) => 
    if (tooltip === document.elementFromPoint(e.clientX, e.clientY)) 
        console.log('false positive');
        return;
    
    console.log('tooltip mouse OUT')

缺点是当浏览器窗口失去焦点时,这也被认为是误报。如果这对您来说是个问题,请查看this answer。

【讨论】:

有没有更多关于这个错误的信息,看起来这是一个非常大的问题,但几乎没有人遇到它(我现在正在经历)?触发它是否需要非常具体的条件? 这里是 Chromium 相关问题:bugs.chromium.org/p/chromium/issues/detail?id=798535 我认为 elementFromPoint 没有得到很好的支持,因为 MDN 给出了 experimental technology 警告 - 但从 caniuse 看来,它似乎在所有移动和桌面浏览器中都得到了完全支持

以上是关于鼠标点击触发鼠标离开的主要内容,如果未能解决你的问题,请参考以下文章

Axure RP使用攻略--入门级

js 鼠标移入触发事件。多次触发。

鼠标点击事件

为啥小弟我的canvas的鼠标事件不会触发

js中鼠标移动事件触发时,如何获得当前鼠标所在元素的内容

常见事件总结