I've just finished implementing a feature in which users can drag files into the browser and drop upon a supporting File Upload plugin, which processes the drop.
However, in order to give users a hint that they can even drop things in the first place, I've implemented a dragover
event to show a div
that says something akin to "Drop Here". This, in turn, hides the div
which has the "Choose File..." button, and replaces it, until the user stops dragging.
But it seems, when I implement this, dragging over the target area is causing flickering. To be clear:
div
with "Choose File" interface is shown.Additionally:
(Warning: the fiddle is very crude.)
Just select some of the text and drag it over the blue box and you will see what happens; it will be obvious the behavior it should not be exhibiting.
var $dropTarget = $("#container");
$(document).bind("dragover", function(e) {
if ($dropTarget.hasClass("highlight"))
return;
$dropTarget.addClass("highlight");
$dropTarget.find("[name='drop']").show();
$dropTarget.find("[name='drag']").hide();
}).bind("dragleave drop", function(e) {
if (!$dropTarget.hasClass("highlight"))
return;
$dropTarget.removeClass("highlight");
$dropTarget.find("[name='drop']").hide();
$dropTarget.find("[name='drag']").show();
});
To be honest, I've got no idea of what to try. There is not extensive documentation on the behavior of dragover
or dragleave
, and I don't even know why this is happening, so I can't even begin to debug it. I feel like dragover
should only fire once, but even dragging around the screen just fires it over and over and over again.
I've looked at Google Images and Google Contacts for their drag-and-drop behavior, but their code is completely minified and unreadable, and I can't even find any specified "drag" behavior.
So, is there some fix to this seemingly odd behavior? If this is a bug in WebKit, which I suspect, is there some brilliant workaround and/or hack I can use?
Thanks to everyone for their time!
After over an hour of scouring, I found someone who had a similar type of issue. It seems that Chrome and Safari (5, at least) fire dragleave
upon entering a child element (and seemingly, upon any changes to that element, including the children being shown/hidden).
The solution is to check if pageX
and pageY
are equal to 0
within dragleave
(but not drop
).
var $dropTarget = $("#container");
$(document).bind("dragenter", function(e) {
if (e.target == this) {
return;
}
$dropTarget.addClass("highlight");
$dropTarget.find("[name='drop']").show();
$dropTarget.find("[name='drag']").hide();
}).bind("dragleave", function(e) {
if (e.originalEvent.pageX != 0 || e.originalEvent.pageY != 0) {
return false;
}
// Could use .trigger("drop") here.
$dropTarget.removeClass("highlight");
$dropTarget.find("[name='drop']").hide();
$dropTarget.find("[name='drag']").show();
}).bind("drop", function(e) {
$dropTarget.removeClass("highlight");
$dropTarget.find("[name='drop']").hide();
$dropTarget.find("[name='drag']").show();
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With