mouseenter/mouseleave ignoring covering element
Asked Answered
S

2

8

It seems that the mouseenter/ mouseleave method is trigger not only when the mouse's coordinate enters the target's client rectangles, but also when another element uncover or cover the target. This is a problem because in my mouseenter callback, I want to display another element E on top of the target. I also want E to disappear upon mouseleave. You can think of this as a overlapping tooltip.

However, when I move my mouse onto the target, mouseenter is fired and element E will cover it. This coverage futher triggers a mouseleave event, so E will disappear. This further triggers a mouseenter event so E will appear again..... Which is quite a headache.

So basically, I am wondering whether there is a version of mouseenter/ mouseleave that only care about whether the mouse enters or leaves the client rectangles of the target, regardless whether the target is covered or not.

update: @arunopjohny created a JS fiddle to illustrate this problem. See comments

Sastruga answered 27/2, 2014 at 2:37 Comment(4)
You can place the overlapping element as a descendant of the target, so that the mouseenter/mouseleave events will not get trigeredOccasionalism
The problem is that the target is inline whereas E is block level. Put E as descendant of the target will drive the browser crazy.. @ArunPJohnySastruga
whether jsfiddle.net/arunpjohny/9fNcY/1 shows your problemOccasionalism
@ArunPJohny Exactly, thanks for creating that. As you can see, there is a short glitch as a sequence of (mouseenter, mouseleave, mouseenter) is fired, instead of a single mouseenter.Sastruga
S
9

Found perfect solution in a relevant question: Ignore mouse interaction on overlay image

The "pointer-events: none;" property will disable any mouse event of the element. More importantly, the event will instead "go through" to the element beneath it. Using this on the overlay element E in my question solves the problem.

Sastruga answered 27/2, 2014 at 6:16 Comment(0)
O
0

Try

jQuery(function ($) {
    $('#target').hover(function () {
        var $target = $(this);
        clearTimeout($target.data('hoverTimer'));
        $('#e').show();
    }, function () {
        var $target = $(this);
        var timer = setTimeout(function () {
            $('#e').hide();
        }, 200);
        $target.data('hoverTimer', timer);
    });

    $('#e').hover(function () {
        clearTimeout($('#target').data('hoverTimer'));
    }, function () {
        $(this).hide();
    });
});

Demo: Fiddle

Occasionalism answered 27/2, 2014 at 3:39 Comment(6)
This solved the problem when target and E has exactly the same position and size. But if E is larger than target, then it won't disappear when you move the mouse out of just the target.Sastruga
@Sastruga can you help to recreate the problem in the fiddleOccasionalism
Yes. That illustrates the problem. But maybe it is the desired behavior on a second thought.Sastruga
@Sastruga what is the desired behavior?Occasionalism
Solution found, as mentioned in my own answer. Thank you for the nice discussion. Here is the fiddle: jsfiddle.net/Up5jYSastruga
The desired behavior is the E shall not interact with mouse event at all. It shall only show and hide and the mouse entering or leaving shall be solely dependent on target.Sastruga

© 2022 - 2024 — McMap. All rights reserved.