user2385136
user2385136

Reputation:

jQuery hover div underneath another layer

Is it possible to ignore all divs that are "above" the element that has hover binded to them with jQuery? For example, I have an element A that has a hover event binded to it, but there also other elements B, C, D that are "absolute positioned" above element A. So when the user's mouse moves over to element B, C, D, the hover event is no longer fired even if B, C, and D are directly above the element. Is it possible to ignore elements B C and D?

UPDATE: I'm actually trying to create a map (element A) with elements B, C, D as area labels. So for example, for a map of New York state, you will have text elements "Manhattan", "New Jersey", etc overlapping the map. This is why I need the hover to fire even if the user has his mouse over the labels.

Upvotes: 13

Views: 16944

Answers (7)

andyb
andyb

Reputation: 43823

If you can use CSS3 then you can set pointer-events:none for the absolutely positioned elements, see demo here.

All modern browsers support this property - only IE9 and below and Opera Mini do not support it (at the time of writing). It also means you will not have any pointer-events for those elements which might not be exactly what you want.

Upvotes: 31

echo
echo

Reputation: 31

The z-index adjustment someone else mentioned works. Make the z-index higher for the item you want to be recognized by hover.

Upvotes: 0

SteveP
SteveP

Reputation: 41

Use e.relatedTarget to determine if the user hovered over one of you nested (absolute) elements. Maybe easier if you give your map labels a class

e.g: To show you labels during a hover state on the map, and only hide them when the user leaves the map

    $("#map").hover(
      function(e) { 
        $(this).find(".labels").fadeIn();
      },

      function(e) {
        if( $(e.relatedTarget).hasClass("maplabel") ) {
          //The user has hovered over a label...Do nothing (or some other function)
        } else {
          // User has left the map and isn't over a label
          $(this).find(".labels").fadeOut();
      }
    );

Upvotes: 4

Jared Farrish
Jared Farrish

Reputation: 49188

Although there are different ways to fix this, probably the simplest would be to add the hover event to all of the elements:

HTML

<div id="a" class="hover"></div>
<div id="b" class="hover"></div>
<div id="c" class="hover"></div>
<div id="d" class="hover"></div>
<div id="state">unhovered</div>

CSS

#a {
    width: 350px;
    height: 300px;
    border: 1px solid #000;
    background-color: #ccc;
}
#b {
    position: absolute;
    top: 35px;
    left: 35px;
    width: 35px;
    height: 30px;
    border: 1px solid #000;
    background-color: #cca;
}
#c {
    position: absolute;
    top: 85px;
    left: 85px;
    width: 35px;
    height: 30px;
    border: 1px solid #000;
    background-color: #cca;
}
#d {
    position: absolute;
    top: 85px;
    left: 135px;
    width: 35px;
    height: 30px;
    border: 1px solid #000;
    background-color: #cca;
}

jQuery

$(document).ready(function(){
    $('.hover').hover(
        function(){
            $('#state').text('hovered');
        },
        function(){
            $('#state').text('unhovered');
        }
    );
});

Example here: http://jsfiddle.net/userdude/H5TAG/

Upvotes: 0

Adam Ayres
Adam Ayres

Reputation: 8900

You could make the z-index of the A element higher then that of the B, C and D elements.

Upvotes: 0

Brad Christie
Brad Christie

Reputation: 101604

The way I see it, you have a few options:

  • Do as Ivarska recommended, and create an empty element over all of them and use that for the trigger.
  • Bind to the mousemove on the entire page and find when it's "inside the box" (i.e. over the target element)--basically, re-invent the hover event. (But not this adds some pretty serious overhead to your page)
  • Redesign

You may be also able to bind to just the target (i.e. A) and any elements you have that may overlap A, then just check if the mouse position within the other control would hypothetically also be inside the A control. Less overhead than binding to the page and checking, but still more than typical.

Upvotes: 4

Ivar
Ivar

Reputation: 4392

The only solution I've got in mind right now is to create an invisible element at the top and give it the hover trigger.

Upvotes: 0

Related Questions