Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery sending mouseevents down the z-axis

Is it possible to send a mousevent down a z-axis? For example, an element has been absolutely positioned on the site above another element. I would like the element below to get the mouseover event even though the other one is blocking it, and even though they are completely unrelated (no parent/child/sibling relationships going on).

This can happen on a good number of elements on the site I'm building, and I'd like a common approach to the problem without having to give some extra JS functionality to every single element that has the chance of this happening.

like image 403
Swader Avatar asked Aug 29 '11 13:08

Swader


People also ask

Which of these are mouse events in jQuery?

Mouse Events in jQuery: mouseenter and mouseleave. mouseup and mousedown. mouseover and mouseout.

What is the jQuery method that binds a jQuery event handler to the JavaScript Onmouse event?

click() Bind an event handler to the “click” JavaScript event, or trigger that event on an element.


2 Answers

First approach

Listen for the mouse event on the element that is on top and trigger the one beneath.

$('#thingOnTop').mouseenter(function(){
  $('#thingUnderneath').mouseenter();
});

This solution doesn't address your requirement of having a general solution for all elements where this issue can occur. It will also not be entirely accurate, if the thing on top is not precisely the same position and dimensions as the thing underneath.

Second approach

Use the pointer-events CSS property. This will allow mouse events to go through things, but it is not supported in older browsers:

.thingsOnTop{
    pointer-events: none;
}

Also note that this will make the thing on top never be the target of a mouse event, rather than in the first solution, where it would trigger the handler for the thing on top and the thing underneath.

JoshNaro's Fourth approach (elaborated)

I was just in the process of adding another approach when Josh beat me to it. As he says, you could listen for the event on the top element and then programmatically find out which other elements are underneath that element for the event's X and Y co-ordinates.

HTML:

<div class="thingThatCouldBeOnTop"></div>
<div class="thingThatCouldBeUnderneath"></div>

JS:

$('.thingThatCouldBeOnTop').mouseenter(function(e){
    $('.thingThatCouldBeUnderneath').filter(function(){
        $this = $(this);
        var offset = $this.offset();
        var height = $this.outerHeight();
        var width = $this.outerWidth();
        return offset.top < e.pageY
            && offset.left < e.pageX
            && (height + offset.top) > e.pageY
            && (width + offset.left) > e.pageX;
    }).mouseenter();
});

$('.thingThatCouldBeUnderneath').mouseenter(function(){
    alert('do something more useful');
});

Please note: This is horribly inefficient. Reducing the set of searched elements to those with a given class helps somewhat (i.e. do $('.thingThatCouldBeUnderneath') rather than $('*')) but this means that you need to add that class to every element that could be underneath another that you want to handle mouse events for. I believe that it is the dimension calculations that causes the majority of the delay. With many potentially 'underneath' elements on the page, this could be too slow.

Here's a working example.

like image 145
Spycho Avatar answered Oct 18 '22 17:10

Spycho


I don't think your going to find a relatively easy solution that completely satisfies your needs, unless maybe the pointer-events trick Spycho mentioned gets you there. However there are a few more unelegant somewhat global approaches you could take:

Third approach

Create a mimic element that is in the same position as your mouse event wanting back element, except with visibility of 'hidden' and higher z-index. Have its mouse events get transferred to the mimicked element.

Fourth approach

  1. Retrieve the mouse event relative to the window
  2. Iterated through each object to determine which element you want the event to apply
  3. Perform action
like image 2
JoshNaro Avatar answered Oct 18 '22 15:10

JoshNaro