我在绝对定位的div中的onmouseout函数遇到了麻烦。当鼠标击中div中的子元素时,mouseout事件发生,但我不希望它发生,直到鼠标离开父元素,绝对div。

我如何防止mouseout事件从发射时,它击中一个子元素没有jquery。

我知道这与事件冒泡有关,但我没有找到如何解决这个问题的方法。

我在这里找到了一个类似的帖子:如何禁用由子元素触发的鼠标退出事件?

但是,该解决方案使用jQuery。


当前回答

有两种方法可以处理这个问题。

1)检查事件。目标结果在你的回调,看看它是否匹配你的父div

var g_ParentDiv;

function OnMouseOut(event) {
    if (event.target != g_ParentDiv) {
        return;
    }
    // handle mouse event here!
};


window.onload = function() {
    g_ParentDiv = document.getElementById("parentdiv");
    g_ParentDiv.onmouseout = OnMouseOut;
};

<div id="parentdiv">
    <img src="childimage.jpg" id="childimg" />
</div>

2)或者使用事件捕获和调用事件。回调函数中的stopPropagation

var g_ParentDiv;

function OnMouseOut(event) {

    event.stopPropagation(); // don't let the event recurse into children

    // handle mouse event here!
};


window.onload = function() {
    g_ParentDiv = document.getElementById("parentdiv");
    g_ParentDiv.addEventListener("mouseout", OnMouseOut, true); // pass true to enable event capturing so parent gets event callback before children
};

<div id="parentdiv">
    <img src="childimage.jpg" id="childimg" />
</div>

其他回答

我用这个让它像魔法一样起作用:

function HideLayer(theEvent){
 var MyDiv=document.getElementById('MyDiv');
 if(MyDiv==(!theEvent?window.event:theEvent.target)){
  MyDiv.style.display='none';
 }
}

MyDiv标签是这样的:

<div id="MyDiv" onmouseout="JavaScript: HideLayer(event);">
 <!-- Here whatever divs, inputs, links, images, anything you want... -->
<div>

通过这种方式,当onmouseout转到子节点、孙子节点等时……的风格。Display ='none'不执行;但是当onmouseout退出MyDiv时,它会运行。

所以不需要停止传播,使用计时器等等……

谢谢例子,我可以从他们做这个代码。

希望这能帮助到一些人。

也可以这样改进:

function HideLayer(theLayer,theEvent){
 if(theLayer==(!theEvent?window.event:theEvent.target)){
  theLayer.style.display='none';
 }
}

然后DIVs标签是这样的:

<div onmouseout="JavaScript: HideLayer(this,event);">
 <!-- Here whatever divs, inputs, links, images, anything you want... -->
<div>

所以更一般,不只是一个div,不需要添加id="…"在每一层。

简单地,我们可以检查e.relatedTarget是否有子类,如果为真则返回函数。

    if ($(e.relatedTarget).hasClass("ctrl-btn")){
        return;
    }

这是为我工作的代码,我用于html5视频播放,暂停按钮切换悬停视频元素

element.on("mouseover mouseout", function(e) {

    if(e.type === "mouseout"){

        if ($(e.relatedTarget).hasClass("child-class")){
            return;
        }

    }

});

我只是想和你分享一些东西。 我在ng-mouseenter和ng-mouseleave事件中遇到了一些困难。

案例分析:

我创建了一个浮动导航菜单,当光标在图标上时切换。 这个菜单在每一页的最上面。

为了处理菜单上的显示/隐藏,我切换了一个类。 ng-class = " {: vm.isHover} " 切换vm。isHover,我使用ng鼠标事件。 ng-mouseenter = " vm。isHover = true" ng-mouseleave = " vm。isHover = false"

目前,一切都很好,并按预期工作。 解决方法简单明了。

接下来的问题是:

在一个特定的视图中,我有一个元素列表。 当光标在列表元素上时,我添加了一个操作面板。 我使用与上面相同的代码来处理该行为。

存在的问题:

我发现当我的光标在浮动导航菜单上,也在一个元素的顶部,有一个相互冲突。 动作面板显示,浮动导航被隐藏。

问题是,即使光标在浮动导航菜单上,列表元素ng-mouseenter也会被触发。 这对我来说毫无意义,因为我认为鼠标传播事件会自动中断。 我必须说我很失望,我花了一些时间来找出那个问题。

第一个想法:

我试着用这些:

$ event.stopPropagation () $ event.stopImmediatePropagation ()

我结合了很多ng指针事件(mouemove, mouveover,…),但没有一个帮助我。

CSS解决方案:

我用一个简单的css属性找到了解决方案,我越来越多地使用它:

pointer-events: none;

基本上,我这样使用它(在我的列表元素上):

ng-style="{'pointer-events': vm.isHover ? 'none' : ''}"

有了这个棘手的,ng-mouse事件将不再被触发,我的浮动导航菜单将不再关闭自己,当光标在它和列表中的一个元素上时。

更进一步说:

正如你所期望的,这个解决方案可行,但我不喜欢它。 我们无法控制事态发展,这很糟糕。 另外,你必须有访问虚拟机的权限。实现这个目标是有可能的,可能是不可能的,但在某种程度上是肮脏的。 如果有人想看的话,我可以做一把小提琴。

然而,我没有其他的解决方案…… 说来话长,我不能给你土豆,所以请原谅我的朋友。 不管怎样,指针事件:没有是生命,所以记住它。

在Angular 5、6和7上

<div (mouseout)="onMouseOut($event)"
     (mouseenter)="onMouseEnter($event)"></div>

然后在

import {Component,Renderer2} from '@angular/core';
...
@Component({
 selector: 'app-test',
 templateUrl: './test.component.html',
 styleUrls: ['./test.component.scss']
})
export class TestComponent implements OnInit, OnDestroy {
...
 public targetElement: HTMLElement;

 constructor(private _renderer: Renderer2) {
 }

 ngOnInit(): void {
 }

 ngOnDestroy(): void {
  //Maybe reset the targetElement
 }

 public onMouseEnter(event): void {
  this.targetElement = event.target || event.srcElement;
  console.log('Mouse Enter', this.targetElement);
 }

 public onMouseOut(event): void {
  const elementRelated = event.toElement || event.relatedTarget;
  if (this.targetElement.contains(elementRelated)) {
    return;
  }
  console.log('Mouse Out');
 }
}

我检查原始元素的偏移量以获得元素边界的页面坐标,然后确保只有当鼠标退出超出这些边界时才触发鼠标退出操作。很脏,但很管用。

$(el).live('mouseout', function(event){
    while(checkPosition(this, event)){
        console.log("mouseovering including children")
    }
    console.log("moused out of the whole")
})

var checkPosition = function(el, event){
    var position = $(el).offset()
    var height = $(el).height()
    var width = $(el).width()
    if (event.pageY > position.top 
|| event.pageY < (position.top + height) 
|| event.pageX > position.left 
|| event.pageX < (position.left + width)){
    return true
}
}