JavaScript鼠标悬停/移出与子元素的问题。

12

我有一个小问题,请求您的帮助。 我有一个 div 元素,里面有一个 img 元素,像这样:

<div id="parent" onmouseover="MyFuncHover()" onmouseout="MyFuncOut()">
    <img id="child" src="button.png" style="visibility: hidden" />
</div>

<script type="text/javascript">
    function MyFuncHover() {
        // Here I have some code that makes the "child" visible
    }

    function MyFuncOut() {
        // Here I have some code that makes the "child" invisible again
    }
</script>

如你所见,该图片是

的子元素。我想只有在离开
时,子元素才会消失。然而,当鼠标移动到图片上时,似乎会调用MyFuncOut()函数(因为我猜测我是通过悬停在图片上离开
)。我不希望这种情况发生。我希望只有在我离开div区域时才调用MyFuncOut()函数。

我不知道当您将鼠标移动到子控件上时,它的父级将调用mouseout事件(即使我仍然在子控件上方,我也同时在父级上方)。我陷入了困境,需要您的建议。谢谢!

更改

好吧,事件冒泡不会在我“mouseout”子元素时将“mouseout”事件发送到父元素。它也不会在我“mouseover”子元素时向父元素发送“mouseover”事件。这不是我需要的。我需要父元素的“mouseout”事件在我“mouseover”子元素时不被发送。你明白了吗?当我不希望例如子元素上的单击事件被传播到父元素时,事件冒泡是有用的,但这不是我的情况。奇怪的是,我在同一个父元素内还有其他元素,当我“mouseover”它们时不会触发父级的“mouseout”事件。

5个回答

24

您可以使用jquery中提供的"mouseenter"和"mouseleave"事件,以下是代码:

$(document).ready(function () {
        $("#parent").mouseenter(function () {
            $("#child").show();
        });
        $("#parent").mouseleave(function () {
            $("#child").hide();
        });
    });

以上是为了绑定一个事件,

<div id="parent">
    <img id="child" src="button.png" style="display:none;" />
</div>

2
我只想用JavaScript来完成它,无论如何还是谢谢,这可能是最后的解决方案。 - ali
2
@ali mouseleave实际上是一个普通的JavaScript事件,所以你可以忽略jQuery部分,直接使用它。与mouseleave唯一的区别在于它不冒泡,因此子元素的mouseleave不会导致父元素获得相同的事件。 - Michael

7
你可以使用下面的解决方案,这是纯 JavaScript 编写的,我已经成功使用过。
var container = document.getElementById("container");
var mouse = {x: 0, y: 0};

function mouseTracking(e) {
    mouse.x = e.clientX || e.pageX;
    mouse.y = e.clientY || e.pageY;
    var containerRectangle = container.getBoundingClientRect();

    if (mouse.x > containerRectangle.left && mouse.x < containerRectangle.right &&
            mouse.y > containerRectangle.top && mouse.y < containerRectangle.bottom) {
        // Mouse is inside container.
    } else {
        // Mouse is outside container.
    }
}
document.onmousemove = function () {
    if (document.addEventListener) {
        document.addEventListener('mousemove', function (e) {
            mouseTracking(e);
        }, false);
    } else if (document.attachEvent) {
        // For IE8 and earlier versions.
        mouseTracking(window.event);
    }
}

我希望这能对您有所帮助。


谢谢...我认为这是一个非常好的解决方案,因为它可以与addEventListener一起使用,为元素进行动态绑定事件。 - hoanganh17b

4
只需在MyFuncOut函数中添加一个if语句,检查目标不是图像即可。
if (event.target !== imageNode) {
     imageNode.style.display = 'none'
}

这里有一个演示 http://jsfiddle.net/HvMjN/4/ ,使用了我之前提到的方法。事实证明,更现代的事件mouseout和mouseenter具有最初期望的行为,所以您可以使用您的代码,只需更改事件类型即可 http://jsfiddle.net/HvMjN/6/。 - Jake
谢谢,唯一的问题是它在IE6上无法运行(错误:对象不支持属性或方法'addEventListener')。不过,我认为可以通过直接使用parent.onmouseover来解决。 - ali
1
只需搜索跨浏览器事件绑定即可。IE6使用attatchEvent。 - Jake

1

只需将子元素的css设置为pointer-event:none;即可。 参见示例:

#parent {
  width: 500px;
  height: 500px;
  border: 1px solid black;
}

#child {
  width: 200px;
  pointer-events: none; # this does the trick
}
<div id="parent" onmouseover="MyFuncHover()" onmouseout="MyFuncOut()">
    <img id="child" src="https://i2.wp.com/beebom.com/wp-content/uploads/2016/01/Reverse-Image-Search-Engines-Apps-And-Its-Uses-2016.jpg?w=640&ssl=1" />
</div>

<script type="text/javascript">
    function MyFuncHover() {
      console.log("mouse over")
    }

    function MyFuncOut() {
      console.log("mouse out")
    }
</script>


如果我有一个子元素作为链接,它将禁用链接。 - diesel94

1
我也遇到了这个问题,而且无法解决。我改用了另一种方法,更加简单,不需要使用JavaScript,因此速度更快,也无法被关闭。
div.container {
    opacity:0.0;
    filter:alpha(opacity="00");
}

div.container:hover {
    opacity:1.0;
    filter:alpha(opacity="100");
}

您甚至可以添加CSS3过渡效果来使其更加平滑。


2
或者只需在正常状态下将其visibility:hidden,而在hover状态下将其visibility:visible。 - Spencer May
这个 filter:alpha(opacity="100"); 是为了IE浏览器,另一个是为了其他所有浏览器。 - Spencer May

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接