10

Setting up the stage:

I have 2 layers one on top of the other. The bottom layer contains links (simple images), The top layer contains advanced tooltip like hovers for the bottom layer. These tooltips can be large (they can overlap onto other links easily, and almost always overlap the link they are tooltipping).

My question:

I'd like my mouseover events to occur on the bottom layer, and then on mouseover display the tooltip in the upper layer. This way as you move off of the bottom link the tooltip in the upper layer goes away, and the tooltip for the new link can show up.

How do I take the events from the top layer and pass them to the layer below instead? So that the top layer is event transparent.

Example HTML:

jQuery(document).ready(function(){
 jQuery('div.tile').click(function(){
  jQuery('#log').html(this.id + " clicked");
  return false;
 });
 jQuery('div#top').click(function(){
  jQuery('#log').html('Top clicked');
  return false;
 });
});
.tile { width: 100px; height: 100px; position: absolute; }
.tile:hover, over:hover {border: 1px solid black;}
.over { width: 100px; height: 100px; position: absolute; display:none}
.stack, #sandwich { width: 400px; height: 400px; position: absolute; }
#tile1 {top: 50px; left: 50px;}
#tile2 {top: 75px; left: 10px;}
#tile3 {top: 150px; left: 310px;}
#tile4 {top: 250px; left: 250px;}
#tile5 {top: 150px; left: 150px;}
#over1 {top: 55px; left: 55px;}
#over2 {top: 80px; left: 15px;}
#over3 {top: 155px; left: 315px;}
#over4 {top: 255px; left: 255px;}
#over5 {top: 155px; left: 155px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>

<div id="sandwich">
 <div class="stack" id="bottom">
  <div class="tile" id="tile1">1</div>
  <div class="tile" id="tile2">2</div>
  <div class="tile" id="tile3">3</div>
  <div class="tile" id="tile4">4</div>
  <div class="tile" id="tile5">5</div>
 </div>
 <div class="stack" id="top">
  <div class="over" id="over1">Tooltip for 1</div>
  <div class="over" id="over2">Tooltip for 2</div>
  <div class="over" id="over3">Tooltip for 3</div>
  <div class="over" id="over4">Tooltip for 4</div>
  <div class="over" id="over5">Tooltip for 5</div>
 </div>
</div>
<div id="log"></div>

With the example javascript I've verified that the events work like normal, and only top is clicked. But I basically want the "over" items to be event transparent.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
silkcom
  • 492
  • 1
  • 5
  • 14

4 Answers4

7

For people stumbling on this nine years later (like I did) the best way to do this now is with the CSS pointer-events property... simply set it to 'none' for your element(s) and behold the magic. No JS required.

https://caniuse.com/#search=pointer-events

charlie roberts
  • 1,659
  • 2
  • 13
  • 7
5

Hope I understand the OP, but you can replicate the event on any selector after the original event has occurred: http://jsfiddle.net/Cr9Kt/1/

In the linked sample, I take the event on the top layer and create a similar event fired on the bottom layer. You can take this further with any individual clicking of each element(as opposed to top and bottom as a whole).

This is a borrowed idea from another question: Triggering a JavaScript click() event at specific coordinates

Community
  • 1
  • 1
Alexis Abril
  • 6,389
  • 6
  • 33
  • 53
  • I think this is the best solution. Now I just need to get it on mouseover and mouseout as well. Thanks – silkcom Dec 05 '10 at 16:32
  • I would be nice of you if you move the code from jsfiddle to an SO snippet so that it's available in your answer directly. Best regards – YakovL Mar 22 '18 at 15:37
0

I am not quite certain that I understand what you are asking for. It sound to me a bit like a tool tip. Here is an example of how to do a tooltip this using jQuery, CSS and HTML.

http://jsbin.com/ilali3/13/edit

Hope that gets you started. If you add some more details, or modify that jsbin with more details we can iterate a bit.

I updated the example a bit to include storing tool tip information into the html element itself using jQuery. This is a bit cleaner.

Bob

rcravens
  • 8,320
  • 2
  • 33
  • 26
  • The main difference between mine and a normal tooltip, is that mine can also overlap the original link as well (sorry I forgot to mention this part). - original question updated – silkcom Dec 03 '10 at 21:33
0

This may seem overly complex and inelegant...it fakes your functionality.. but it works ;)

$(document).ready(function(){
    var tileData = new Array();

    // get coordinate data for each tile
    $('div.tile').each(function(){
        var tileInfo = {};   
        tileInfo.id = this.id;
        tileInfo.text = $(this).text();
        tileInfo.width = $(this).outerWidth();
        tileInfo.height = $(this).outerHeight();
        tileInfo.position = $(this).position();
        tileInfo.coords = {};
        tileInfo.coords.top = tileInfo.position.top;
        tileInfo.coords.right = tileInfo.position.left + tileInfo.width;
        tileInfo.coords.bottom = tileInfo.position.top + tileInfo.height;
        tileInfo.coords.left = tileInfo.position.left;

        tileData.push(tileInfo);
    });

    $('div.tile').click(function(){
        $('#log').html(this.id + " clicked");
        return false;
    })       

    $('div#top').click(function(event){
        $('#log').html('Top clicked');

        // try to find tile under your mouse click
        for(i=0; i<tileData.length;i++){
            if(
                event.pageX >= tileData[i].coords.left &&
                event.pageX <= tileData[i].coords.right &&
                event.pageY >= tileData[i].coords.top &&
                event.pageY <= tileData[i].coords.bottom
            )  {
                // found a tile! trigger its click event handler
                $('#' + tileData[i].id).click();
            }
        }  

        return false;
    });
});

Try it here: http://jsfiddle.net/neopreneur/vzq4z/1/

Nick G
  • 960
  • 6
  • 7