Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event object eaten by jQuery animation callback

I have a problem with event object passed to the function in drop event. In my code, div#dropArea has it's drop event handled by firstDrop function which does some animations and then calls the proper function dropFromDesktop which handles the e.dataTransfer.files object. I need this approach in two separate functions because the latter is also used further by some other divs in the HTML document (no need to duplicate the code). First one is used only once, to hide some 'welcome' texts.

Generally, this mechanism lets you drag files from desktop and drop them into an area on my website.

Here's, how it looks (in a shortcut):

function firstDrop(ev) {
    var $this = $(this);

    //when I call the function here, it passes the event with files inside it
    //dropFromDesktop.call($this, ev);

    $this.children('.welcomeText').animate({
        opacity: '0',
        height: '0'
    }, 700, function() {
        $('#raw .menu').first().slideDown('fast', function() {
            //when I call the function here, it passes the event, but 'files' object is empty
            dropFromDesktop.call($this, ev);
        });
    });
}

function dropFromDesktop(ev) {
    var files = ev.originalEvent.dataTransfer.files;
    (...) //handling the files
}

$('#dropArea').one('drop', firstDrop);
$('some_other_div').on('drop', dropFromDesktop);

The problem is somewhere in jQuery.animation's callback - when I call my function inside it, the event object is passed correctly, but files object from dataTransfer is empty!

Whole script is put inside $(document).ready(function() { ... }); so the order of function declarations doesn't matter, I guess.

like image 660
matewka Avatar asked Nov 13 '22 14:11

matewka


1 Answers

I suspect your problem is related with the lifetime of the Event object. Unfortunately, I have no clue about the cause of it. But, there is a way to workaround it that I can think of and it is keeping a reference to Event.dataTransfer.files instead.

var handleFileList = function(fn) {
  return function(evt) {
    evt.preventDefault();
    return fn.call(this, evt.originalEvent.dataTransfer.files);
  };
};

var firstDrop = function(fileList) { ... }
var dropFromDesktop = function(fileList) { ... }

$('#dropArea').one('drop', handleFileList(firstDrop));
$('some_other_div').on('drop', handleFileList(dropFromDesktop));​
like image 81
Alexander Avatar answered Nov 15 '22 07:11

Alexander