Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag-and-drop to div behind absolutely positioned div

I am doing drag and drop the HTML5-way (i.e. no jQuery draggable/droppable). I have a drop target (a div) that is partially obscured by another, absolutely positioned div, like so:

<div id="drop-target" style="width:100%; height:500px; background-color:blue;" />

<div id="obscuring-div" style="width:40%; height:150px; position:absolute; top:10px; left: 10px; background-color:red;" />

When I drop items on the absolutely positioned obscuring-div, is there any way to make the drop event trigger on drop-target instead of obscuring-div?

like image 781
MW. Avatar asked Sep 02 '25 15:09

MW.


2 Answers

The comments from Pete led me to a javascript solution for forwarding click events through layers, and I could do something similar for drop events. For future reference, here's the code:

var element = $('#drop-target');
// This element should be droppable
element.on('dragover', function (event) {
    event.preventDefault();
});
// This element should be droppable
element.on('dragenter', function (event) {
    event.preventDefault();
});

element.on('drop', function (event) {
    // Find position of drop event
    var xPos = event.originalEvent.clientX,
        yPos = event.originalEvent.clientY;

    // Temporarily hide this element
    element.hide();

    // Find the element that is the real drop target
    var dropTargetBelow = $(document.elementFromPoint(xPos, yPos));

    // Trigger the drop event on real drop target
    dropTargetBelow.trigger(event);

    // Show this element again
    $(this).show();
});

This also works when the elements are stacked, for example if there are three obscuring divs in front of the drop target.

like image 71
MW. Avatar answered Sep 05 '25 04:09

MW.


Just for the record: a similar approach using the elementsFromPoint method and the native dispatchEvent:

someHandler(event): {
  let elements = document.elementsFromPoint(event.clientX, event.clientY);
  let target = elements.find(e => e.matches('#obscuring-div'));
  target.dispatchEvent(new DragEvent('drop', {
    // anything you need to pass; works without that in the simplest case
  }));
}
like image 22
Andrey Stukalin Avatar answered Sep 05 '25 05:09

Andrey Stukalin