Gustavo
Gustavo

Reputation: 1683

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

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>

Upvotes: 1

Views: 2311

Answers (3)

Marco Bonelli
Marco Bonelli

Reputation: 69477

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

Upvotes: 2

Paul S.
Paul S.

Reputation: 66394

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

Upvotes: 1

interesting eyy
interesting eyy

Reputation: 97

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

Upvotes: -2

Related Questions