-->

jQuery hover div underneath another layer

2020-08-11 06:08发布

问题:

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.

回答1:

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.



回答2:

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.



回答3:

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();
      }
    );


回答4:

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.



回答5:

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



回答6:

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/



回答7:

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