4
votes

Made a fiddle for this: http://jsfiddle.net/terjeto/MN4FJ/

My problem is that dragleave fires when you drag a file from desktop into the box and over the text inside the box. (drag a file into box will make the border solid -> drag the file over the text inside the box and the border will be dashed:->which is not what I want).

Is this a browser bug? (firefox 9@win).

I also put in a box for mouse up/down which works just fine so you can compare the two.

How can I achieve the correct dragenter / dragleave behaviour?

PS. I bind to body because I need the event-delegation in my real app.

4

4 Answers

2
votes

This is a well documented shortcomming of the spec. As Peter-Paul Koch points out here

A function like this might help you work out if the target element is a child of the target area that you want to drop the file onto.

function isChildElement(parent, child) {
    var childParent = child;
    while (childParent) {
        if (childParent == parent) {
           return true;
        }
        childParent = childParent.parentNode;
    }
    return false;
},
2
votes

I've written a little library called Dragster to help me deal with this issue, it works everywhere except IE (where it just does nothing).

1
votes

The issue is relatively well known, but solutions are all pretty 'hacky'. I came across a workaround that fixes it in my case and should be adaptable for most situations.

I listen for dragenter events on the container (a box) of my possible dropzones. Events fire whenever the drag moves from one element to another and bubble to the container. When the target is one of my drop zones (or possibly a child within the drop zone but that wasn't necessary in my case since you can't get to the children without entering the surrounding box first) then I set the droppable highlighting, just as normal.

When the dragenter event fires on the container itself then I remove the highlighting from the previous element because I must have left it. For a dragenter event, the element that was highlighted is the relatedTarget so it is easy to find and there is no need for a dragleave event listener.

Note that you may have the remove the highlighting explicitly following a drop, depending on your exact drop logic.

0
votes

I had the same problem and finally figured out a stable solution. Here is a plugin called draghover, which works cross browsers. Check it out here: https://github.com/bingjie2680/jquery-draghover