Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show overlay on 'dragenter' when dragging a file from desktop to the browser

i'm trying to achieve the same effect as on imgur.com (drag a file from the desktop to imgur.com and you'll see a cool overlay). already have a working solution thanks to this post: Event propagation, overlay and drag-and-drop events

BUT: i find the solution rather unsatisfying. the problem is $(document).on('dragenter') gets fired multiple times when hovering over child elements. i was looking for an event that gets fired ONCE when i enter the viewport and ONCE when i leave the viewport so i could have a clean $overlay.fadeIn() and .fadeOut() on dragenter and dragleave.

i solved it with a transparent element that fills the whole viewport. i then call dragenter on that transparent element instead of on $(document). with $('*:visible').live('dragenter') i then show the hidden and the real overlay. $('#transparentOverlay').on('dragleave') hides the overlays. pretty hacky but it works (at least in safari/chrome/firefox)

but just the selector $('*:visible').live() gives me a headache...

anyone have a better suggestion?

like image 235
Philip Paetz Avatar asked Feb 09 '12 09:02

Philip Paetz


3 Answers

A more lightweight version of the answer above:

;(function() {
    var dragTimeout;

    $(document).on('dragenter', function(e) {
        // dragenter code
    });

    $(document).on('dragleave', function(e) {
        dragTimeout = setTimeout(function() {
            dragTimeout = undefined;
            // your dragleave code
        });
    });

    $(document).on('dragover', function(e) {
        if (dragTimeout) {
            clearTimeout(dragTimeout);
            dragTimeout = undefined;
        }
    });
})();
like image 142
Rijk Avatar answered Nov 16 '22 07:11

Rijk


Try it like this, which works well for me. Essentially, it's imitating the dragenter and dragleave events, but only using dragover:

;(function() {
    var isOver = false, interval;

    $(document).on('dragover', function(e) {
        e.preventDefault();

        clearInterval(interval);

        interval = setInterval(function() {
            isOver = false;
            clearInterval(interval);

            /*** callback for onDragLeave ***/
        }, 100);

        if (!isOver) {
            isOver = true;

            /*** callback for onDragEnter ***/
        }
    });
})();
like image 29
Artod Avatar answered Nov 16 '22 06:11

Artod


May need to see more code/errors you're experiencing. Have you tried a simple boolean to check when your event has fired and limit the subsequent events?

var dragging = false;

$(document).on('dragenter', function(){
    if(!dragging){
        //DO SOMETHING
        dragging = true;
    }
});

$(document).on('dragleave', function(){
    if(dragging){
        //DO SOMETHING
        dragging = false;
    }
});
like image 45
Steve O Avatar answered Nov 16 '22 06:11

Steve O