Javascript 如何为旧浏览器模拟mouseenter和mouseleave DOM事件?

Javascript 如何为旧浏览器模拟mouseenter和mouseleave DOM事件?,javascript,events,mouseevent,Javascript,Events,Mouseevent,用div创建一个窗口并使用mouseover-mouseout有一个已知的问题:如果里面有一个子div,它将触发mouseout。mouseenter和mouseleave最近解决了这个问题,因为除非鼠标点离开根div(真正的窗口),否则不会开火。不幸的是,有很多浏览器无法识别这些新事件,如所示: 火狐7 铬14 狩猎5.1 我认为可以使用mouseover和mouseout的事件冒泡处理来产生所需的效果。可能吗?还有别的(更好的)办法吗?或者就是做不到 Obs.:在此项目中不使用jQuer

用div创建一个窗口并使用mouseover-mouseout有一个已知的问题:如果里面有一个子div,它将触发mouseout。mouseenter和mouseleave最近解决了这个问题,因为除非鼠标点离开根div(真正的窗口),否则不会开火。不幸的是,有很多浏览器无法识别这些新事件,如所示:

  • 火狐7
  • 铬14
  • 狩猎5.1
我认为可以使用mouseover和mouseout的事件冒泡处理来产生所需的效果。可能吗?还有别的(更好的)办法吗?或者就是做不到

Obs.:在此项目中不使用jQuery

编辑:我的测试代码:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Mouse Events Tester</title>
<script>
var inside = function(e){
    console.log("I am inside!");
}

var outside = function(e){
    if(e.target !== this) console.log("Now outside...");
}

function targetOnly(handler) {
    return function (e) {
        if (e.target === this)
            return handler.apply(this, arguments);
        return;
    };
}

function ini(){
    document.getElementById("win").addEventListener("mouseover", inside, false);
    document.getElementById("win").addEventListener("mouseout", outside, false);
}


</script>
</head>

<body onload="ini();">
<div id="win" style="border:#000 solid 2px; background-color:#999;">
    <p>Window</p>
    <div id="anything" style="border:#000 dashed 1px; background-color:#CCC;">
    <p>An object inside the window</p>
    </div>
</div>
</body>
</html>

鼠标事件测试仪
内部变量=函数(e){
log(“我在里面!”);
}
外部变量=函数(e){
如果(e.target!==this)console.log(“现在在外面…”);
}
函数targetOnly(处理程序){
返回函数(e){
如果(例如,目标===此)
返回处理程序.apply(这个,参数);
返回;
};
}
函数ini(){
document.getElementById(“win”).addEventListener(“鼠标悬停”,内,假);
document.getElementById(“win”).addEventListener(“鼠标输出”,外部,错误);
}
窗口

窗内的物体


我花了大约一个小时在这上面,我得出了以下代码:

Element.prototype.childOf = function(p){var c=this;while((c=c.parentNode)&&c!==p);return !!c};

el = document.getElementById('your-element-id');

el.onmouseover = function(e) {
    if (e.target == e.currentTarget && !e.fromElement.childOf(e.currentTarget) && !e.toElement.childOf(e.currentTarget)) {
        // you are in
    }
}

el.onmouseout = function(e) {
    if (e.target == e.currentTarget && !e.fromElement.childOf(e.currentTarget) && !e.toElement.childOf(e.currentTarget)) {
        // you are out
    }
}

将不可见div作为display的子级添加:none,当鼠标悬停被触发时,显示不可见div,使用不可见div触发mouseout, 像这样的

    <div id="parent" onmouseover="functionover()" >
        <div id="child1" onmouseout="functionout()"
         style='position:absolute;display:none;width:100%;height:100%;'"></div>
        <div id="yourchildelement" ></div>
    </div>

    <script>
    function functionover()
    {
    $('#child1').css('display','block');
    ....
    }
    </script>


使用
event.target
可以查看事件
e
来自哪个节点。如果您需要经常检查类似的内容,那么如果您编写一个函数包装器,只在
e.target==this

function targetOnly(handler) {
    return function (e) {
        if (e.target === this)
            return handler.apply(this, arguments);
        return;
    };
}

foo.addEventListener('mouseover', targetOnly(handerA));
foo.addEventListener('mouseout' , targetOnly(handerB));


用于

的MDN页面查看
e.target
,如果
e.target!==这
,事件来自一个孩子的点头你有理由支持这些旧浏览器吗?@JamesMontagne:我正在使用Safari 5.1进行开发,列表中的东西对我有用,对吧?@PaulS:有趣!你为什么不发一个答案呢?这样就行了。我会等待其他答案,因为我提到了泡泡,让我们看看是否有人有话要说。@GustavoPinent捕捉和泡泡只是代表了事件传播的方向,它们与此类问题无关……我今天早上测试了它,它有一个有趣的效果:当进入内部div时(在一个级别上),它没有启动,但是当它返回到根div时,它启动了(而且它不应该启动)。我认为解决方案会更复杂一些。通过以下方式更改您的表达式:“!(e.target.id==e.currentTarget.id)”已经解决了一半的问题。当鼠标从内部DIV返回时,它仍然会启动,但是,鼠标盖也会启动,因此它可以被管理。您可以尝试修复您的答案。@GustavoPinent我编辑了我的代码,我希望为此获得奖励,因为我在尝试实现此结果时确实浪费了一个小时,哈哈。现在它工作了。我没有使用jQuer在这个项目中,我有一个好朋友。