Javascript 通过单击触发鼠标删除

Javascript 通过单击触发鼠标删除,javascript,google-chrome,dom,mouseevent,Javascript,Google Chrome,Dom,Mouseevent,我有一个绝对定位的div,我试图跟踪鼠标何时在上面移动,何时离开。不幸的是,点击框中的文本偶尔会触发mouseleave事件 演示: 我怎样才能防止这种情况 JS HTML 这似乎是一个bug(我可以在Chrome中复制它,每次点击都会让鼠标快速下降和上升) 我建议通过检查触发事件时鼠标是否仍在元素上方来解决此问题: tooltip.onmouseleave = (e) => { if (tooltip === document.elementFromPoint(e.clientX

我有一个绝对定位的div,我试图跟踪鼠标何时在上面移动,何时离开。不幸的是,点击框中的文本偶尔会触发mouseleave事件

演示:

我怎样才能防止这种情况

JS

HTML

这似乎是一个bug(我可以在Chrome中复制它,每次点击都会让鼠标快速下降和上升)

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

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

缺点是,当浏览器窗口失去焦点时,这也被认为是误报。如果这是您的问题,请检查。

我也遇到了此错误。在我的例子中,我将标签包装的复选框添加到一个列表中,并将列表包装在一个div中。我还使用了一些属于

标记的列表项。如果快速单击复选框和标签,有时会在包装div上触发
mouseleave
事件。这不应该发生,因为所有单击的元素都是
div.wrapper
的子元素

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

这是复制品的gif照片。在线索区域内单击(具有一定的强度和移动),单击标签和输入框中的事件,然后您会看到两个mouseleave事件错误地触发,当鼠标真正离开蓝色区域时,会触发第三个mouseleave事件


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

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

private handleMouseLeave(event: MouseEvent) {
    if(event.relatedTarget || event.toElement){
        // do whatever
    }
    // otherwise ignore
}
根据我在Chrome v64上的测试,每当快速点击导致触发
mouseleave
事件时,这两个值都将为
null
relatedTarget
用于旧浏览器兼容性

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


注意:Firefox最新版本(2018年2月)似乎会在每次点击我的菜单时触发
mouseleave
!我得调查一下,@trincot的回答几乎对我有用。就我而言,我在处理爆米花。当我点击一个按钮时,它会触发一个弹出框,显示在触发按钮的顶部。因此
document.elementFromPoint(e.clientX,e.clientY)
返回popover元素而不是触发按钮。我是这样解决的:

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
});
mouseeave(ev:MouseEvent){
常量触发器:HTMLElement=document.getElementById(“#myTrigger”);
const triggerRect=trigger.getBoundingClientRect();
常量假阳性=IsWithingArct(ev.clientX,ev.clientY,triggerRect);
如果(!假阳性){
//做需要做的事
}
}
函数IsWithingArct(x:number,y:number,rect:ClientRect){
const xisinin=x>rect.left&&xrect.top&&y
检查主按钮是否已按下

tooltip.onmouseleave=(e)=>{
如果(如按钮!==1){
console.log('tooltip mouse OUT')
}
}

对我来说很好:您正在尝试哪个浏览器?这在mozilla和chrome中非常有效。请检查扩展名和类似的Toocrome-当点击字符时,这种情况很少发生。似乎和光标的变化是一致的。我保证这不是什么玩笑-我知道复制可能很少见。我是在Chrome最新的马厩里(不是金丝雀)。如果有人知道为什么会发生这种情况以及如何预防,我很乐意听到。这不是问题的答案。如果这个问题的另一个答案不能解决你的问题,那么你可以问一个新问题。一旦你有了足够的声誉,你也可以评论到原来的帖子,提供你对这个明显错误的体验。谢谢你发布这个帖子。这是一个答案,因为它表明这是一个错误。我刚刚花了一个小时想弄明白为什么会发生这种事!!是否有更多关于这个bug的信息,这似乎是一个非常重要的问题,但几乎没有人遇到它(我现在是)?触发它需要非常具体的条件吗?以下是与铬相关的问题:我认为
elementFromPoint
没有得到很好的支持,因为MDN提供了
实验技术
警告-但是来自caniuse,它似乎在所有手机和桌面浏览器中都得到了充分的支持。这一定要花很长时间才能找到:)@T4NK3R是的,它花了整个周六晚上比较了不同活动的MouseEvent属性!!!谢谢你的评论,很高兴在调试之后有一些反馈:-)不客气-让我不用在游戏中添加jQuery:)-顺便说一句:在我的Firefox(61.0.2)中没有看到任何有趣的事情。。
...
  wrapper.addEventListener(
    'mouseleave',
    (e) => {
      logger('mouseleave fired');
      console.log('mouseleave fired', e);
    },
    false
  );
...
private handleMouseLeave(event: MouseEvent) {
    if(event.relatedTarget || event.toElement){
        // do whatever
    }
    // otherwise ignore
}
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
});