移动活动元素在Internet Explorer中丢失mouseout事件

时间:2010-09-10 15:52:13

标签: javascript javascript-events mouseevent raphael mouseout

在我使用的库中,我的任务是将元素移动到dom的前面。 (我把它做得更大所以我需要看到它,然后在鼠标移出时缩回它。)

我正在使用的库有一个简洁的解决方案,它使用活动元素上的appendChildren将其移动到其父级的末尾,从而进一步朝向dom的末尾,然后在顶部。

问题是我相信因为您正在移动的元素是您在鼠标移动事件上移动的元素丢失了。您的鼠标仍在节点上,但未触发mouseout事件。

我已经删除了功能以确认问题。它在Firefox中运行良好,但在任何版本的IE中都没有。我在这里使用jquery来提高速度。解决方案可以是普通的旧javascript ..这可能是一个偏好,因为它可能需要重新上传。

我不能在这里使用z-index,因为元素是vml,库是Raphael,我正在使用toFront调用。使用ul / li进行示例以简单示例显示问题

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="js/jquery.min.js" type="text/javascript"></script>
<style>
    li
    {
        border:1px solid black;
    }
</style>
</head>
<body>
<ul><li>Test 1</li></ul>
<ul><li>Test 2</li></ul>
<ul><li>Test 3</li></ul>
<ul><li>Test 4</li></ul>
<script>
$(function(){
    $("li").mouseover(function(){
        $(this).css("border-color","red");
        this.parentNode.appendChild(this);
    });

    $("li").mouseout(function(){
        $(this).css("border-color","black");
    });
});
</script>
</body>
</html>

编辑:这是指向js粘贴bin的链接,以便查看它的实际效果。 http://jsbin.com/obesa4

**编辑2:**在发布更多信息之前,请查看所有答案的所有评论。

4 个答案:

答案 0 :(得分:15)

问题在于 IE以不同的方式处理mouseover ,因为它在元素上的行为类似于mouseentermousemove。在其他浏览器中,它只是mouseenter

所以即使你的鼠标进入了目标元素并且你已经改变了它的外观并重新添加它的父亲mouseover仍然会为鼠标的每次移动而触发,该元素会再次重新连接,这会阻止其他事件处理程序被调用。

解决方案是模拟正确的mouseover 行为,以便onmouseover中的操作只执行一次。

$("li").mouseover( function() {
    // make sure these actions are executed only once
    if ( this.style.borderColor != "red" ) {
        this.style.borderColor = "red";
        this.parentNode.appendChild(this);
    }
});

<强>实施例

  1. Extented demo of yours
  2. Example演示浏览器之间的mouseover差异(奖金:原生javascript)

答案 1 :(得分:1)

我能够在父级上使用嵌套div和mouseenter事件:

<div id="frame">
  <div class='box'></div>
  <div class='box'></div>
  <div class='box'></div>
  <div class='box'></div>
</div>
...
$('#frame').mouseenter(function() {
     $(".box").css("border-color", "black");
});

这是使用Raphael的工作版本:

http://jsfiddle.net/xDREx/

答案 2 :(得分:1)

我修改了@ galambalazs&#39;回答是因为我发现如果我在li元素上快速徘徊就失败了,因为一些元素仍会保留mouseover效果。

我提出了一个解决方案,通过在mouseover偶数被触发时将这些元素推送到堆栈,从而消除未能触发mouseover事件的元素上的悬停状态。无论何时调用mouseovermouseout事件,我都会弹出此数组中的元素并删除其上的样式:

$(function(){

    // Track any hovered elements
    window.hovered = [];

    $("li").mouseover(function() {
        // make sure that these actions happen only once
        if ( $(this).css("border-color") != "red" ) {
            resetHovered ();  // Reset any previous hovered elements
            $(this).css("border-color","red");
            this.parentNode.appendChild(this);
            hovered.push(this);
        }
    });

    $("li").mouseout(function(){
        resetHovered();  // Reset any previous hovered elements
    });

    // Reset any elements on the stack
    function resetHovered () {
        while ( hovered.length > 0 ) {
            var elem = hovered.pop();
            $(elem).css("border-color","black");
        }
    }
});

我已经使用IE 11测试了这个解决方案。可以找到一个功能示例here

答案 3 :(得分:0)

那是不可思议的,似乎只是IE浏览器(但VML也是如此)。如果父元素指定了高度,则可以将mouseout处理程序附加到父级...但听起来这样在您的情况下不起作用。您最好的选择是在相邻元素上使用鼠标悬停来隐藏它:

$(function()
{
    $("li").mouseover(function()
    {
        $("li").css("border-color", "black");
        $(this).css("border-color", "red");
        this.parentNode.appendChild(this);
    });
});

或SVG。您可以在SVG中使用z-index。