Skip to content
Advertisement

Event propagation, overlay and drag-and-drop events

I want to overlay a div over the viewport when the user drags a file onto the window.

However, I’m having trouble with the event propagation. When I set the overlay to display: block it appears to fire off a dragleave event and then another dragenter and then another dragleave again, so it’s always in a post-dragleave state. Of course I call e.stopPropagation() and e.preventDefault() on the event object, but it doesn’t seem to make a difference.

The console.log() output when you drag something over the window:

dragenter
dragenter
dragleave
dragenter
dragleave

The css. #overlay is set to display: none by default, but will show if body has the dragenter class:

    body {
        position: absolute;
        height: auto;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        margin: 0;
        padding: 0;
    }

    #overlay {
        position: absolute;        
        height: auto;
        width: auto;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: url(bg.png) repeat-x top right, url(bg.png) repeat-x bottom left, url(bg.png) repeat-y top right, url(bg.p
ng) repeat-y bottom left;
        display: none;
    }

    body.dragenter #overlay {
        display: block;
    }

The JavaScript; add the ‘dragenter’ class on dragenter and removes it on dragleave:

$(document).on('dragenter', function (e) {
    e.stopPropagation();
    e.preventDefault();
    console.log('dragenter');
    $(document.body).addClass('dragenter');
});

$(document).on('dragleave', function (e) {
    e.stopPropagation();
    e.preventDefault();
    console.log('dragleave';
    $(document.body).removeClass('dragenter');
});

The html:

<body>
<div id="overlay">...</div>
...    
</body>

Advertisement

Answer

Thanks to Scottux, that led me onto the right track.

Only problem was it also covered up the rest of the page, so none of the elements or inputs were clickable. I had to hide #dragOverlay by default with “display: none” and display it on this event

// Display an overlay when dragging a file over
$('*:visible').live('dragenter', function(e) {
    e.stopPropagation();
    $('body').addClass('drag-enter');
});
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement