简体   繁体   中英

How to emulate mouseenter and mouseleave DOM events for old browsers?

Making a window with a div and using mouseover - mouseout has the known issue: if there is a child div inside, it will fire mouseout. This were recently solved by mouseenter and mouseleave because doesn't fire unless the mouse point go out the root div, the real window. Unfortunately, there is a lot of browsers the wont recognize those new events, as shown in this article . :

  • FireFox 7
  • Chrome 14
  • Safari 5.1

I think it might be possible to use event bubbling handling with mouseover and mouseout to produce the desired effect. Is it possible? Is there another (better) way? Or it just can't be done?

Obs.: not using jQuery in this project.

EDIT: my code for testing:

<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>

I spent like an hour on this and I came out with this code:

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
    }
}

Using event.target you can see from which Node an Event e originated from. If you'll need to check things like this often it might be easiest if you write a function wrapper which only invokes your handler if 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 page for event.target here

add an invisible div as child with display:none, when the mouseover is triggered, display the the invisible div, trigger mouseout with the invisible div, something like this.

    <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>

something like this, hope this helps...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM