13

在我正在使用的库中,我的任务是将元素悬停在 dom 的前面。(我把它放大了,所以我需要看到它,然后在鼠标移出时将它缩小)。

我正在使用的库有一个简洁的解决方案,它appendChildren在活动元素上使用将其移动到其父元素的末尾,从而进一步靠近 dom 的末尾并依次位于顶部。

问题是我相信因为你正在移动的元素是你悬停在mouseout事件上的那个元素丢失了。您的鼠标仍在节点上,但未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 粘贴箱的链接,以查看它的运行情况。http://jsbin.com/obesa4

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

4

4 回答 4

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. 你的扩展演示
  2. 演示 mouseover浏览器之间差异的示例(奖励:本机 javascript)
于 2010-10-23T22:14:44.520 回答
1

我修改了@galambalazs 的答案,因为我发现如果我很快将鼠标悬停在 li 元素上它会失败,因为某些元素仍然会保留mouseover效果。

我想出了一个解决方案,通过在触发mouseover事件时将这些元素推送到堆栈来删除未能触发事件的元素的悬停状态mouseover。每当调用mouseoverormouseout事件时,我都会从该数组中弹出元素并删除放置在其上的样式:

$(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 测试了这个解决方案。可以在这里找到一个功能示例。

于 2014-05-23T21:28:22.540 回答
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/

于 2010-10-20T19:06:12.737 回答
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。

于 2010-09-11T00:53:14.203 回答