12

I have this little problem and I am requesting for your help. I have a div element, inside which I have an img element, like this

<div id="parent" onmouseover="MyFuncHover()" onmouseout="MyFuncOut()">
    <img id="child" src="button.png" style="visibility: hidden" />
</div>

<script type="text/javascript">
    function MyFuncHover() {
        // Here I have some code that makes the "child" visible
    }

    function MyFuncOut() {
        // Here I have some code that makes the "child" invisible again
    }
</script>

As you, see, the image is a child of the div. I want that only when I leave the div, the child to disappear. Yet, it looks like when I move the mouse over the image, the MyFuncOut() function is called (because, I suppose, I leave the div by hovering the image). I don't want that to happen. I want the MyFuncOut() function to be called only when I leave the div area.

I didn't know that when you move your mouse over a child control, it's parent calls the mouseout event (even if I am over the child, I am still over the parent, too). I am trapped into this and I need a little of your good advice. Thanks!

CHANGES

O.K. Event bubbling will not send the "mouseout" event to the parent when I "mouseout" the child. It also won't send the "mouseover" event to the parent when I "mouseover" the child. That's not what I need. I need the "mouseout" event of the parent to not be sent when I "mouseover" the child. Get it? Event bubbling is useful when I don't want, for example, a click event on the child to be propagated to the parent, but this is not my case. What is weird is that I have other elements inside the same parent that don't fire the "mouseout" event of the parent when I "mouseover" them.

ali
  • 10,927
  • 20
  • 89
  • 138

5 Answers5

24

you can use "mouseenter" and "mouseleave" events available in jquery, here is the below code,

$(document).ready(function () {
        $("#parent").mouseenter(function () {
            $("#child").show();
        });
        $("#parent").mouseleave(function () {
            $("#child").hide();
        });
    });

above is to attach an event,

<div id="parent">
    <img id="child" src="button.png" style="display:none;" />
</div>
Vishal Gowda
  • 511
  • 1
  • 3
  • 11
  • 2
    I wanna do it with JavaScript only, thanks anyway, could be a last solution. – ali May 17 '12 at 09:21
  • 2
    @ali mouseleave is actually a plain javascript event, so you can ignore the jQuery part and just use it directly. the only difference between it and mouseleave is it doesn't bubble, so the child mouseleave won't cause the parent to get the same event. – Michael Mar 01 '16 at 23:45
7

You can use the solution below, which it's pure javascript and I used with success.

var container = document.getElementById("container");
var mouse = {x: 0, y: 0};

function mouseTracking(e) {
    mouse.x = e.clientX || e.pageX;
    mouse.y = e.clientY || e.pageY;
    var containerRectangle = container.getBoundingClientRect();

    if (mouse.x > containerRectangle.left && mouse.x < containerRectangle.right &&
            mouse.y > containerRectangle.top && mouse.y < containerRectangle.bottom) {
        // Mouse is inside container.
    } else {
        // Mouse is outside container.
    }
}
document.onmousemove = function () {
    if (document.addEventListener) {
        document.addEventListener('mousemove', function (e) {
            mouseTracking(e);
        }, false);
    } else if (document.attachEvent) {
        // For IE8 and earlier versions.
        mouseTracking(window.event);
    }
}

I hope it helps.

Pedro Alvares
  • 479
  • 5
  • 9
  • Thank...I think it's very good solution because it can be used with addEventListener for dynamic binding event for elements – hoanganh17b Sep 02 '15 at 08:13
4

Just add an if statement to your MyFuncOut function which checks the target is not the image

if (event.target !== imageNode) {
     imageNode.style.display = 'none'
}
Jake
  • 558
  • 4
  • 12
  • here is a demo http://jsfiddle.net/HvMjN/4/ using the method I was talking about above. It turns out the more modern event mouseout and mouseenter have the behaviour you originally expected so you can use your code just change the event types http://jsfiddle.net/HvMjN/6/ – Jake May 17 '12 at 12:36
  • Thanks man, the only problem is that it doesn't work on IE6 (Error: Object doesn't support property or method 'addEventListener'). Yet, I think that can be solved by directly parent.onmouseover – ali May 17 '12 at 14:19
  • 1
    just search cross browser event binding. ie6 uses attatchEvent – Jake May 17 '12 at 21:48
1

I've had problems with this too and couldn't get it to work. This is what I did instead. It's much easier and isn't JavaScript so it's faster and can't be turned off.

div.container {
    opacity:0.0;
    filter:alpha(opacity="00");
}

div.container:hover {
    opacity:1.0;
    filter:alpha(opacity="100");
}

You can even add the CSS3 transition for opacity to give it a smoother feel to it.

eriegz
  • 335
  • 3
  • 10
Spencer May
  • 4,266
  • 9
  • 28
  • 48
1

Simply set css of the child element pointer-event:none; See example:

#parent {
  width: 500px;
  height: 500px;
  border: 1px solid black;
}

#child {
  width: 200px;
  pointer-events: none; # this does the trick
}
<div id="parent" onmouseover="MyFuncHover()" onmouseout="MyFuncOut()">
    <img id="child" src="https://i2.wp.com/beebom.com/wp-content/uploads/2016/01/Reverse-Image-Search-Engines-Apps-And-Its-Uses-2016.jpg?w=640&ssl=1" />
</div>

<script type="text/javascript">
    function MyFuncHover() {
      console.log("mouse over")
    }

    function MyFuncOut() {
      console.log("mouse out")
    }
</script>
Keyang
  • 1,828
  • 1
  • 12
  • 17