Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering multiple drop handler interrupts for stacked elements

I have some <div> elements set up with droppable to receive thumbnail images that are dropped on them, dragged from a gallery. <img> elements are also set up to accept these thumbnails, so I could have an image on top of an image. The drop handlers recover the image from the thumbnail and and append it to the body.

A problem occurs when there are multiple divs and imgs stacked on top of each other and a thumb gets dropped on the stack. The drop handler for each of these stacked elements gets called when the thumb is dropped and wants to process the thumb into an image and append it to the body. The result is multiple copies of the same image.

How can I process the thumbnail drop just one time for all the interrupts that the drop generates so I end up with just a single image?

Thanks

like image 974
Steve Avatar asked Mar 28 '26 01:03

Steve


1 Answers

I have created a small proof of concept on jsfiddle (http://jsfiddle.net/9M8gP/21/). A quick breakdown:

processDroppedElement searches the list of dropped elements and selects the appropriate element. You can obviously customize the selection criteria. After processing the event, it resets state variables appropriately.

var processDroppedElement = function() {

    $("p").html("");

    var targetElement = null;
    var targetZ = -1;

    for (var i in droppedElements) {
        var element = droppedElements[i];
        var zOrder = $( element ).data("zOrder");
        if (zOrder && zOrder > targetZ) {
            targetElement = element;
        }            
    }

    if (targetElement) {
         $( targetElement )
              .addClass( "ui-state-highlight" )
              .find( "p" )
                .html( "Dropped!" );
        droppedElement = null;
    }

    $("#draggable").css({
        'left': $("#draggable").data('originalLeft'),
        'top': $("#draggable").data('origionalTop')
    });

    droppedElements = [];
};

This section of code defines basic variables used to manage dropped elements and firing the processDroppedElement function.

var droppedTimer;
var droppedElements = [];

var queueDroppedElement = function(element) {
    droppedElements.push(element);
}

The drop function simply queues elements and creates a timeout to launch the processing logic. It pre-clears any existing timeouts to ensure the function is only run once. This is a bit of a hack, but functional

$( ".droppable" ).droppable({
  drop: function( event, ui ) {

      var myZorder = $( this ).data("zOrder");
      console.log("zOrder: " + myZorder);

      queueDroppedElement(this);

      clearTimeout(droppedTimer);
      droppedTimer = setTimeout(processDroppedElement, 50);
  }
});
like image 154
Jaime Torres Avatar answered Mar 31 '26 04:03

Jaime Torres



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!