2

I am using jQuery UI draggable. I have stack of elements with z-indexes and one element that is completely over the draggable container. I can't set it to draggable because click events aren't getting through to it because it is behind another element.

How can I access that element and get it to respond to the mouse events?

My CSS:

#top {
    width:500px;
    height:500px;
    z-index:5;
    background-color:rgba(255,0,0,0.5);
    position:absolute;
}
#child {
    width:300px;
    height:300px;
    z-index:4;
    background-color:rgba(0,255,0,0.5);
    position:absolute;
    top:50px;
    left:50px;
}
#draggable {
     width:200px;
    height:200px;  
    z-index:4;
    background-color:rgba(0,0,255,0.5);
    position:absolute;
    top:10px;
    left:10px;
}

My HTML:

<div id="top"></div>
<div id="child">
    <div id="draggable"></div>
</div>

And my Javascript:

$(function(){

    $("#draggable").draggable({
        containment: "child"
    });

});

I have also put all this code into JS Fiddle to demonstrate: http://jsfiddle.net/wvSqk/

Thanks

betamax
  • 13,431
  • 9
  • 38
  • 55
  • 1
    Lets figure this out: why do you want the huge div to be over the rest in the first place? – Hans Wassink Nov 09 '11 at 12:05
  • Including the second parant div inside the first parent div make it works but I don't know if it is really what you want : http://jsfiddle.net/wvSqk/2/ – Guillaume Cisco Nov 09 '11 at 12:10
  • @Hans Wassink Unfortunately, it is a design/layout requirement and this div *must* be over the top. There's not much I can do about it but work with it. – betamax Nov 09 '11 at 12:19
  • @Guillaume Cisco No, that changes the z ordering so that the draggables are on top of the parent instead of behind – betamax Nov 09 '11 at 12:20
  • 1
    Well, I dont think that this is possible then mate... Maybe you can make a script that checks what pixel you click, and then what element is underneath your div. Knowing that you can temporarily hide the top or something. Elements are never clickthrough in your browser, sorry... – Hans Wassink Nov 09 '11 at 12:43

4 Answers4

3

Just solved this without event forwarding or anything complicated - Simply put another, transparent, layer on top of everything, and mark it as draggable. and whenever it is dragged copy its position to the target layer underneath.
Something like this:

var $draggableOverlay = $("#draggableOverlay");
var $draggableTarget = $('#draggableTarget');

$draggableOverlay.draggable({
    drag: function() {
        $draggableTarget.css('left', $draggableOverlay.css('left'));
        $draggableTarget.css('top', $draggableOverlay.css('top'));
    }
});

There are more tweaks you can apply to make it look nice, and close some edge cases, but it works.

seldary
  • 6,186
  • 4
  • 40
  • 55
1

another possible solution is to apply the draggable to the top-most element, and return the element that should actually be dragged as a 'helper'. just note that you shouldn't actually pass the to-be-dragged element itself - as it gets removed when dragging completes - but a copy of it; something like:

$( "#top" ).draggable({
  cursor: "move",
  cursorAt: { top: -12, left: -20 },
  helper: function( event ) {
     return $( "#draggable").clone();
  }
});

this is just a start of course (e.g. the original element should be hidden, and 'cursorAt' needs to be calculated), but i'm happy to help if you need further guidance on this.

schellmax
  • 5,678
  • 4
  • 37
  • 48
1

There has been a question similar to this already asked: css 'pointer-events' property alternative for IE.

Now I know it's not exactly the same, but it does deal with mouse events being passed from one element to another. Check out the links there and see if it can help you out in your situation.

:)

Community
  • 1
  • 1
Kyle
  • 65,599
  • 28
  • 144
  • 152
0

You have to put the #top div z-index to a lower than #child z-index

#top {
    ...
    z-index:3;
}

If you can't change the CSS, you can change it using jquery when the mouse is over #top div.

Something like that

 var oldValue=  $("#top").css('z-index');
 var newValue = $("#child").css('z-index')-1;

 $("#top").hover(function(){$("#top").css('z-index',newValue)},
                   function(){$("#top").css('z-index',oldValue)});

it's a little buggy, but you have to adjust. http://jsfiddle.net/wvSqk/4/

Jean-Charles
  • 1,690
  • 17
  • 28