The HTML5 drag and drop disaster

After spending about a day and a half in testing I am forced to conclude that the HTML5 drag and drop module is not just a disaster, it’s a fucking disaster.

The module should be removed from the HTML5 specification straight away, and conforming browsers should disable it at their earliest opportunity pending a complete rewrite from the ground up.

Web developers MUST NOT (in the sense of RFC 2119) use HTML 5 drag and drop. They should use old-school scripts instead.

Before we continue I’d like to say that in general I thoroughly approve of the HTML5 specification. Exactly because the spec has such an overall quality I was so surprised (and, frankly, a bit confused and hurt) to find drag and drop a steaming pile of bovine manure.

In fact, it’s so outrageously bad that I’ve gone on strike. I refuse to do any more research on drag and drop. Go do it yourself. Or don’t bother. Whatever. I don’t care.

What follows is a rant laced with profanity. No apologies. Drag and drop deserves no better.

Who got us into this mess?

Microsoft “designed” and implemented drag and drop way back in 1999, when IE 5.0 was released. IE versions has supported it ever since.

This specification was terribly bad, as we’ll see in a moment. Microsoft dropped the ball majorly here.

Still, while Microsoft is to blame initially, the HTML5 WG and the other browser vendors are accessories to the crime.

One of the guiding principles of HTML5 and its WHAT-WG precursors is to document everything that already works in browsers but previous Working Groups couldn’t be arsed to specify, such as innerHTML and offsetWidth.

Although I thoroughly support that principle and see how it applies to the Microsoft drag and drop module, I still think that some form of critical reflection might have been in order in this particular case.

Hixie said:

The drag-and-drop API is horrible, but it has one thing going for it: IE6 implements it, as do Safari and Firefox.

Now that is undeniably true. God knows why, but Firefox, Safari, and Chrome have shoveled it straight into their rendering engines, and critical reflection be damned. Only Opera has retained its sanity.

Interoperability is very important. But not at any price. The price is too high when it comes to drag and drop.

The transcript of my testing sessions

OK, so what exactly is wrong with the HTML5 drag and drop module?

I’ll show you.

Below follows an approximate transcript of my testing sessions. It shows you what I went through and why I wrote this entry.

This was an exceptionally bad case. The worst I’ve encountered since the demise of Netscape 4, in fact. That’s why the transcript includes profanity. Lots and lots of profanity.

Too many events

There are no less than seven events associated with drag and drop: dragstart, drag, dragover, dragenter, dragleave, drop, and dragend.

This seems rather a lot for a series of actions that can be accurately described by the mousedown, mousemove, and mouseup events.

In itself that’s not a disaster, just bad API design. We have to pick a few events and ignore the rest.

[ ... tinker ... ]

[ ... tinker ... ]

Say. Fucking. WHAT?!?

The drop event fires when the user drops an element he’s dragging.

And, you see, dropping the element you’re dragging is the POINT of this entire module.

So drop is the most important event. But it doesn’t fire. Let’s see ...

[ ... tinker ... ]

[ ... consult spec and example ... ]

OK, got it.

For the drop event to fire at all, you have to cancel the defaults of both the dragover and the dragenter event.

[ ... ]

... say WHAT?!?

OK, let’s try again:

The default action of the dragover and the dragenter events is NOT being able to drop an element. And you have to cancel these default actions in order to drop an element. Obviously.

[ ... ]

Say. Fucking. WHAT?!?

OK, one more time:

The dragover and dragenter events exist for the sole reason of forcing web developers who want to perform a drop action to cancel their obscure default actions.

You’re kidding me.

[ ... crickets ... ]

You’ve GOT to be FUCKING kidding me!

I’m not going to cancel the default actions of not one but two of your bullshit events in order to get the most important action in the entire fucking module working.

Then we won’t play. Nyaa, nyaa...

You bunch of fucking idiots don’t have the fuckingest clue what you’re doing!

[ ... crickets ... ]

Now listen carefully, and you might actually learn something:

Default actions are supposed to be defined in positive terms: if you take this action, that will happen, unless the script cancels it. That’s how JavaScript events were designed to work.

[ ... crickets ... ]

No wonder I can’t give up smoking.

[ ... drag ... ]

Calm down, calm down. Let it be. Maybe it’ll go away by itself.

Do something else first.

Return to normalcy

When I defined a dragstart event handler, the other events just stopped firing in IE. All of them.

When I studied Remy Sharp’s test case, however, I found it works in IE8 despite the presence of the dragstart event.

This is a strange inconsistency, especially since the spec is supposed to be based on the IE implementation. So either the spec has overlooked a special case in which all the other events are canceled, or IE sometimes doesn’t implement its own implementation.

I’m guessing the latter right now. Browser bug #1. To be retested, ascertained, and documented.

Phew, finally something normal.

Maybe the ... other thing ... will turn out not so bad, after all.

But first some more events.

dragthis

The drag event is like mousemove, except that it fires during a drag operation. Hey, this makes sense! Works everywhere? Yup. Next.

dragthat and dragsomethingelse

In theory dragenter and dragleave could be great events, since they fire when you enter or leave an HTML element in the middle of a drag operation. If that element is a valid drop target you could change its styles ondragenter and ondragleave to indicate this fact to the user.

With the spec being based on the Microsoft API, I expected dragenter and dragleave to emulate mouseenter and mouseleave. But they didn’t. Not even in IE. They’re based on mouseover and mouseout and suck every bit as badly. And their names are wrong.

Mouseover and mouseout are terrible because they bubble up all the time and make it very hard to distinguish important events from unimportant ones. If I mouse over (or drag enter) a child element of the one that the event is set on, it also fires. And that’s exactly what we don’t want. The events will fire incessantly the whole time the mouse is above the element, and we have to work hard in order to distinguish useful events from useless ones.

Mouseenter and mouseleave, on the other hand, fire only when you enter and leave the element they’re defined on, and they don’t bubble. That makes them much easier to use.

They are Microsoft extensions, by the way, and excellent ones at that. They work only in IE.

Note that originally mouseenter and mouseleave had exactly the same IE only compatibility pattern as drag and drop. Mouseenter and mouseleave are a good idea, drag and drop ... isn’t. Guess what the other browsers chose to implement?

No wonder web development is such a fucking pain with fucking morons in charge of the browsers.

Wait, that could be construed as an insult to morons.

Ah, what the fuck.

dragbullshit

Dragover, now, has nothing to do with mouseover. It’s exactly the same as the drag event, except that you can set it on any element instead of just the document. Or something. Whatever.

Why do we need the dragover event if we already have the drag event?

[ ... fume ... ]

To cancel its default action!

If we didn’t have to cancel its default action the dragbullshit event would have no fucking point!

And we can’t have pointless events in our nice specification, now, can we?

So we give it a default action. A very complicated default action.

That has to be canceled. Absolutely, positively has to be canceled.

[ ... crickets ... ]

Anybody LISTENING to what I say?

[ ... drag ... ]

I deserve a fucking MEDAL for this. Above and beyond the call of fucking DUTY.

draggable

Then we have the draggable attribute that, when set to true, allows an element to be dragged. It only works in Firefox. Links and images are draggable by default.

Actually that’s a pretty good idea.

Wow, I can finally say something nice. But to whom?

I’m assuming that draggable is an HTML5 addition because it doesn’t work in IE, and therefore I’m assuming I can congratulate the HTML5 WG with having had a good idea.

You see, I can’t find the Microsoft documentation on drag and drop, so I can’t check whether draggable is supposed to be supported in IE.

In practice it isn’t, that’s for sure.

(If you know where to find the Microsoft documentation, don’t bother leaving a comment. Meanwhile I don’t care any more.)

Safari fuckup

Next problem.

In order to get drag and drop working in Safari, add this to your CSS!

#tobedragged {
	-khtml-user-drag: element;
}

[ ... ]

Q: Hi, how do you want me to present this element to the user?
A: It’s draggable.

[ ... ]

Fuck you, Safari team. Fuck. You.

Wait, let’s rephrase that. A gentle question might help more than a rant.

Dear Safari team, does “separation of presentation and behaviour” mean anything to you?

[ ... crickets ... ]

Thought not.

[ ... drag ... ]

Fuck you anyway.

Drop effects? Or drag effects?

The dropEffect property might actually set the drag effect. At least, that’s how I read the spec right now.

I could be wrong here. I have no fucking clue what a drag (or drop) effect is, and you don’t, either.

As an experiment I set the property to every single value the spec allows, and it made no difference whatsoever in any browser.

Then I discovered I had to set effectsAllowed to all in order to decree that all drop effects (which really may be drag effects) are allowed. This made no difference, either — no browser reacted to my setting of dropEffect by showing any of the now-allowed drag (or drop?) effects.

Some browsers report the value of effectsAllowed as copyLink, by the way. Just after I set it to all . A little creativity to show their good spirits, I presume.

And why would I need to give permission at all? Setting dropEffect to the desired value indicates that I command (and, by implication, permit) the effect to take place.

Doesn’t it?

[ ... crickets ... ]

[ ... crickets ... ]

Oh, fuck you. I give up.

Strike

If you’re still not convinced that drag and drop sucks, read Francisco Tolmasky’s article on bugs and problems he encountered.

In fact, from his piece it almost seems as if the browser vendors have trouble implementing drag and drop.

Gee, I wonder why that is.

But I’m not going to figure it out. I’ve had enough.

Any unanswered questions you might have after reading this piece will remain unanswered for all eternity, as far as I’m concerned. I don’t see why I should spend another two to three (unpaid) days on this pile of junk.

Go do your own research for a change.

And don’t bother leaving pointers to useful articles and stuff. I just don’t care any more, and I’m certainly not going to read them.

I’m on strike.

This is the blog of Peter-Paul Koch, mobile platform strategist, consultant, and trainer. You can also follow him on Twitter.
Atom RSS

I’m around at the following conferences:

(Data from Lanyrd)

Categories:

Monthlies:

Comments

Comments are closed.

1 Posted by Ian Hickson on 21 September 2009 | Permalink

Yeah, I made up "draggable" because it seems there's no way to drag _elements_ in IE, only selections. Glad you like it. :-)

I wrote a blog post myself while reverse engineering this... interesting... API that Microsoft invented:

http://ln.hixie.ch/?start=1115899732&count=1

I added an intro to the HTML5 spec recently, btw, which might help with introducing authors to this API so that they don't feel quite as bad as you do. :-)

2 Posted by ppk on 21 September 2009 | Permalink

Thanks, I hadn't found that article.

Sorry for the rant; hope you don't take it personally, but I feel that drag and drop should be rewritten from the ground up.

In fact I have some ideas about that. I want to think about it a bit more, and then publish them.

3 Posted by Tom on 21 September 2009 | Permalink

After reading this, I need a fucking heart surgeon!

4 Posted by Liam the lemming on 21 September 2009 | Permalink

This isn't a disaster. It's a goddamn *horror story*.

As with all the testing that's gone before it: Thank you, PPK, for suffering this unspeakable torment so we don't have to - and, now, know better than to try.

5 Posted by Robbert Broersma on 21 September 2009 | Permalink

Dismissing the dragenter/dragleave events in favour of mousedown/mouseup is quite contradictory to your rant in the mouse events compatibility table on browser vendors not implementing mouseenter/mouseleave.

Also, I think when it comes to browsers, there can never be too much specific events available (as long as they all implement one specification).

6 Posted by Bartek on 21 September 2009 | Permalink

About the weird cancel-default-action thing... There may actually be some logical reasons to it.

Isn't it the case that, by default, no elements should accept dropping a dragged element on them? I think that it's a reasonable action to reject any dragged element by default. If it was the other way around, *ANY* element on the page would accept dragged elements: you could drop them anywhere, because the default action would be to accept them (allow drop).

You don't want to tell every single element on the page (beside one or two) that it shouldn't accept dragged elements (because only the one or two elements are the valid drop areas).

So, by default, an element doesn't accept dropping.

Adding an event listener (e.g. dragenter) alone shouldn't change the behaviour of the element. It shouldn't change (or prevent) the default action. So you must prevent it manually, in the listener.

7 Posted by Francisco Tolmasky on 21 September 2009 | Permalink

The worst part is that after much investigation, it appears that this API is more or less useless for tomorrow's breed of applications, which theoretically was the whole point of HTML 5.

Take Bespin for example. Since Bespin is rendered entirely into one canvas element, its prohibitively difficult (or actually impossible), to start a drag and drop. This is because the API is completely declarative, requiring you to mark entire elements as draggable or not. So you can't for example say "if you drag upwards, then drag and drop", because by the time you've figured this out its to late to cancel (or not cancel?) the event.

The prevent default thing is also a mess, because it prevents all defaults from happening. You wind up in situations where you want to cancel drags but not text selection, but are only given the option to do both. Quite frustrating.

I wouldn't expect much to be done about this however, I made a very conservative request to whatwg already and was basically told to wait until HTML 6.

8 Posted by ppk on 21 September 2009 | Permalink

Good point about the text selection; I hadn't thought of that yet.

Are you going to write a bit more about how drag and drop doesn't give us what we need? You seem to have done more research than I have.

9 Posted by kl on 21 September 2009 | Permalink

it's useless for 280slides and API is crap. So it's neither nice nor powerful.

This API needs to be dropped, dragged behind a shed and shot in the head.

10 Posted by Derek Martin on 21 September 2009 | Permalink

Ok, that's it. Maybe it *is* finally time for me to get out of web development, and try something sane, like direct-mail marketing :P

11 Posted by Ricardo on 21 September 2009 | Permalink

HTML6? The one which will be fully implemented by 2037?

12 Posted by Anonymous Someone on 21 September 2009 | Permalink

The issues I always came across was that it that the APIs were roughly line up with how the clipboard works. This is not a bad thing, it generally makes it easy for components to accept drop operations in a similar fashion to accepting a paste.

However security considerations have largely neutered setting the clipboard in the browser, setting the content of drag operation is unlikely to fare any better.

In the browser drag operations should be event rich, but work more like existing browser events. They should just drag node references around.

Dragging out of a browser will probably end up working just like the clipboard does. (ie out of the script writers control) Dragging into the browser could probably work a little like the proposed file api.

13 Posted by Thomas Broyer on 21 September 2009 | Permalink

You're harsh!

Let's try to "explain" some points:

1. dnd as specified in HTML5 and (more or less) implemented in IE, WebKit and Firefox 3.5, allows much more than what you can hack with mouse events; things that are not possible at all with an "old-school script", and *that's* the whole point of it: allowing dragging something (under your control!) to another application and/or receiving something from another application. Those things can be URLs, plain text, HTML, images, files, etc.

2. You've asked for a Microsoft specification? Well, you know they don't do that, but they have some documentation nevertheless http://msdn.microsoft.com/en-us/library/ms537658(VS.85).aspx

3. those 7 events are to be split into two groups: the ones firing at the *source* (the thing being dragged; namely: dragstart, drag and dragend, Microsoft also lists dragenter there but doesn't describe its role in this case) and the ones firing at potential *targets* (dragenter, dragover, dragleave and drop). You complained dragover was just like drag, well it fires at the same time, but on different objects.

[...to be continued...]

14 Posted by Thomas Broyer on 21 September 2009 | Permalink

[...continued...]


4. the drop event: for the drop event to fire, you must have previously told the browser that this (the "current" element) is a valid drop target; and this must be done as soon as your mouse pointer enters the element (dragenter). Because the default behavior is to *not* be a drop target, cancelling the event actually makes the event target a drop target. As for the dragover event, I admit it's a bit "strange"; but it allows you to change the dropEffect depending on where the mouse is within the drop target (some kind of "image map" for DnD).

5. As you said, -khtml-user-drag (or -webkit-user-drag) is a shame (it's noting to do with presentation, so shouldn't be CSS); well, draggable is the equivalent, just better.

6. Finally, dropEffects vs. effectsAllowed; again, it's all about drag source vs. drop target: the source object sets the effectsAllowed (if it's read-only, it won't allow "move"; if it's inherently temporary, it won't allow "link", etc.) and the drop target choose a dropEffect among them.

Ah, and the introduction added by Ian makes all this much clearer overall if you ask me.

15 Posted by Michael Wales on 21 September 2009 | Permalink

I have one major problem with drag-drop in HTML5, just based on looking at the spec (I haven't attempted to use it, this reply will explain why).

HTML/xHTML is content - it's there to provide the content to the user in a semantic and readable fashion. It's not there to make it look pretty - it's not there to make it do fancy things, it's only job is to provide content.

Drag-and-drop is dynamic functionality. It has nothing to do with the content itself - it is 100% based in the users interaction with that content, which is outside the scope of HTML/xHTML.

HTML5 has disappointed me through-and-through. It's a half-hazardly thrown together spec that is only seeing adoption at this point in time because it has been in the works for so long. It is nowhere near ready and personally, I don't see any need for it.

I've tried to write documents to the HTML5 spec - it makes my job twice as hard, the code is harder to read (since HTML5 semantic elements don't really "do" anything) you still have to sprinkle divs/lis in to do anything functional. Just a waste of lines and deeper indentation throughout the document.

I'm sticking the xHTML 1.0 Strict - it's served me fine and HTML5 provides absolutely no benefit as a developer.

16 Posted by Connie Swail on 21 September 2009 | Permalink

You wrote: "There are no less than seven events associated with drag and drop: dragstart, drag, dragover, dragenter, dragleave, drop, and dragend."

There is an eighth event: dragnet.
It's available at your local video store, or (illegally) through a BitTorrent.

My advise, forget about it all for a while and watch a movie from the pre-WWW era.

17 Posted by Nabil Elisa on 21 September 2009 | Permalink

i'd had similar experiences with drag and drop in the past but figured that i was simply too dumb to understand it. glad to see that i'm not alone!

i appreciate all the hard work that hixie (and co) has to do in keeping an evolving spec under control, but i definitely believe that this particular api should be rewritten from scratch with sanity in mind. franciscos post had some great ideas in it, and i suspect you too have a few of your own. please post them publicly and maybe we can get more people supporting them...

18 Posted by Karl Adam on 21 September 2009 | Permalink

I think since this is quirksblog I should point out these comments do not render properly on mobile safari and if they go over a certain length are simply clipped.

19 Posted by Chris on 21 September 2009 | Permalink

The spec may be a disaster, but your rant is absolutely brilliant :-)

20 Posted by Alejandro Moreno on 21 September 2009 | Permalink

@Thomas Broyer:

I think you missed the point. I'm sure persistent people can figure out how to work with the API and do fabulous things with it, but I feel PPK is fundamentally opposed to its abysmal design in the midst of the mostly reasonable and logical spec that HTML5 is.

21 Posted by l.m.orchard on 21 September 2009 | Permalink

I have to second Thomas Broyer on the reason for the 7 events, which you seem to have missed in the rant:

Half of them fire on the thing dragged, while the others fire on the thing underneath potentially receiving the drop.

That's something you just can't do with "old school scripts" without resorting to homemade collision detection on coordinates. And forget about using event delegation on a list parent to easily detect a drag/drop on one of a hundred or so list elements.

And not only that, but the events on the drop targets can receive drags from outside the browser, which is a complete non-starter in old school scripts.

So, rant away, but please remember there's at least one baby in the olympic-sized pool of bathwater

22 Posted by Ross Boucher on 21 September 2009 | Permalink

@karladam They render correctly. It's just that the lack of a scroll bar on iPhone doesn't let you know that the comment is scrollable.

And because of the way scrolling behaves in MobileSafari, it triggers two finger scrolling mode. Give that a shot on long comments and you will see.

23 Posted by Darkimmortal on 21 September 2009 | Permalink

I think you're wrong. The spec seems logical coming from a WinForms background, not from old drag+drop APIs in browsers.

24 Posted by ohnoes on 21 September 2009 | Permalink

The dnd APIs are verbose, yes. You want APIs to be verbose (within reason) - the opposite is much much much worse.

At first glance, the 'return false' approach does seem odd, but it makes a lot of sense..

As with most object-oriented APIs (on mac and windows) you can override the default behavior/handler. If you return false, you basically say 'well, I'm not going to handle this event; OS, you do it'

You might not know this design as a web developer, but millions of actual developers understand it.

25 Posted by Ms2ger on 21 September 2009 | Permalink

@Alejandro Moreno: "the mostly reasonable and logical spec that HTML5 is"—seriously? Even the HTML5 spec itself doesn't agree with you. I quote: "It must be admitted that many aspects of HTML appear at first glance to be nonsensical and inconsistent."

26 Posted by Darkimmortal on 21 September 2009 | Permalink

@ohnoes

+1, OP is obviously not a developer.

27 Posted by xavier on 21 September 2009 | Permalink

Gosh, some technical analysis actually making sense. Someone is putting soul, and curse words, in the spec. May he be blessed.

The only logical alternative being to wait until everyone forgets it and keep implementing it as today using js, or that your favourite js library has spent enough time to hide the mess and present it into a digestible api that allows you to forget about how smelly it it below.

28 Posted by Michael Butler on 21 September 2009 | Permalink

I hope they work out a proper implementation of drag N drop, because it would be HUGELY beneficial (to users) with photo/video sharing on the web, allowing us to seamlessly copy files from our desktops to the web without having to go through annoying dialogs and clicking.

29 Posted by Karl Adam on 22 September 2009 | Permalink

@boucher You're right, but that may be the most undiscoverable interaction I've ever seen both due to the lack of scrollbar and the before never used two finger scroll gesture in Safari for an inner scrollview. Might be better to just show the full comment on Mobile Safari. Thanks for the tip though, next time I'll be able to read the comments without running back to desktop.

P.S. It's still a weird interaction on the desktop

30 Posted by Sander Aarts on 22 September 2009 | Permalink

ohnoes: "You might not know this design as a *web* developer, but millions of *actual* developers understand it." [emphasis mine]

Oh dear, here we go again.

31 Posted by Erik Arvidsson on 22 September 2009 | Permalink

WebKit has draggable as well if you got build 532.0 or newer:

https://bugs.webkit.org/show_bug.cgi?id=26262

32 Posted by F1LT3R on 22 September 2009 | Permalink

YOU SAID: "Default actions are supposed to be defined in positive terms: if you take this action, that will happen, unless the script cancels it. That’s how JavaScript events were designed to work."

I SAY: "Huge industrial sledgehammer hitting the unmissably large nail on it's over-sized head. Over and over."

Thank you.

33 Posted by Ryan McGrath on 22 September 2009 | Permalink

How on earth did the spec ever get this far while being this cluttered?

I'd also really like to know why anybody ever considered it a "plus" (in any sense) that a new spec "works" in IE6. At the risk of playing the same old broken record, that browser needs to die, and it shouldn't matter if newer specs are supported in older versions of IE.

34 Posted by geeves on 22 September 2009 | Permalink

I've been waiting for this breaking point for years. you do good and very valuable work for the web community here and I've long wondered why you've never called MS, Mozilla or Safari out on their glacier-like or haphazard development of "components" for "standards". (Yes, I'm lumping all 3 together, and I know it's not entirely their individual faults, if you have one moving forward without the others you have the next div vs layer argument amongst browsers.)

But this seems ridiculous, almost as bad as OS X not focusing on dropdowns.

35 Posted by Doug Schepers on 22 September 2009 | Permalink

FWIW, we've added mouseenter and mouseleave to the DOM3 Events spec, and we have general commitment from the browser vendors to implement it. Check it out in the latest editor's draft:

http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#event-type-mouseenter

(Oh, and this will be completed and implemented more than a decade before 2022... )

36 Posted by Jacob Rossi on 22 September 2009 | Permalink

I agree, dragenter and dragleave should be closer to mouseenter and mouseleave (since they are more like CSS :hover). @Schepers: thanks again for adding mouseenter/mouseleave.

Moreover, why does HTML5 say copy/paste should be treated as a form of drag/drop (and thus fire drag/drop related events)?

If copy/paste fires drag/drop events then many sites may have unnecessary UI flicker because they have engineered some drag/drop state UI.

I complained about this to the webapps WG and the only real counterpoint I received was that treating copy/paste like drag/drop enables mobile users (without mouse) to trigger drag/drop.

See my thread here:
http://lists.w3.org/Archives/Public/www-dom/2009JulSep/0109.html

Hixie replied later on, saying that he could add a flag indicating if it's a pragmatic drag or an interactive one. But I haven't seen that added (correct me if I'm wrong).

I think it makes sense for drag/drop events themselves to be the indication of an interactive data transfer. To the user and the web author, copy/paste and drag/drop are 2 different things. This is the way it's currently implemented in most browsers' event models. Why muddle it?

37 Posted by Brad Neuberg on 22 September 2009 | Permalink

I'm confused... are you saying HTML 5 drag and drop sucks? Just kidding, I'm being a smart ass. I actually hadn't cracked this part of the HTML 5 spec open myself; disappointing to see that it's a pile of turd. Sometimes worse is better, except when it's worse.

38 Posted by Mickael on 22 September 2009 | Permalink

Hello y'all. I implemented HTML5 dnd, and I agree it's not easy to understand at first sight. But once you got it, I find it very powerfull. Drop events bubble : that's welcome because you can use the well-known "event delegation" technique ( http://decafbad.com/blog/2009/07/15/html5-drag-and-drop ).

39 Posted by Jonny Axelsson on 22 September 2009 | Permalink

HTML5 drag&drop has a potentially huge benefit over scripted drag&drop in usability and accessibility.

Scripted drag&drop generally doesn't work at all if the user has no access to a mouse. A good number of devices don't have a mouse attached, phones, TVs, the Nintendo Wii... Drag&drop also requires considerable coordination on behalf of the user. For most of us drag&drop is liberating, but I too have spent time cursing over a badly designed drag&drop application.

Of course a such API should be so convenient and efficient to use that it is preferable to hacking it out with a script.

http://dev.opera.com/articles/view/accessible-drag-and-drop/
http://my.opera.com/jax/blog/2009/07/09/keyboard-drag-and-drop-html-and-accessibility
http://html5doctor.com/accessibility-native-drag-and-drop/

40 Posted by Speednet on 22 September 2009 | Permalink

OMG, I have to bite my lip or something to stop the uncontrollable laughter. By the time I got to the Safari section I lost it.

I guess part of my reaction is that I recently shared a sliver of your experience, when I had to add drag-and-drop to my jQuery Watermark plugin (http://jquery-watermark.googlecode.com/). All I had to do was hide the watermark when something is dragged over a text element, and that took days to get to a point that sort-of works well.

I am constantly amazed that the HTML5 team does not fix stuff like this for good. As it stands, the official spec probably won't leave draft status for another 15 years, so it's not like there are many chances to fix bad specs.

41 Posted by Christophe Eblé on 22 September 2009 | Permalink

We've also implemented a native D&D abstraction layer on top of IE, FF and WEBKIT and yes, that was really a BIG pain in the a**

On the other hand, this effort
has given us a wealth of possibilities, impossible to achieve with simulated DnD.

42 Posted by Mark McDonnell on 22 September 2009 | Permalink

Thank you so much for the line...

"Fuck you, Safari team. Fuck. You."

...that had me in stitches :)

43 Posted by Sebastian Markbåge on 23 September 2009 | Permalink

ppk, you're lucky you gave up so quickly.

I've been trying to implement a these APIs - including backwards compatibility.

The APIs actually does have SOME merit when you get down to the cross-window operations. It enforces the source and the target to be completely unaware of each other. That makes it much easier to build new sources and targets.

That being said, the actual implementations are horrible. It's quite an overstatement that they work in all browsers.

There is a whole bunch of Windows specific bugs in WebKit. Some dropEffect combinations doesn't work at all in different UAs. The WebKit events are fired in the wrong order. Mozilla blocks mouse position in the drag event. setDragImage has a bunch of browser specific quirks, if it works at all. Browsers handle mime types in the OS differently. IE only accepts text/uri. Mozilla has custom mime types for OS drag and drops... and much more.

The most annoying of all... IE blocks the thread during drag operations, so you can't have setTimeout... i.e. no animations during drag!

44 Posted by David Semeria on 23 September 2009 | Permalink

I've been saying for a while that the whole D+D implmentation would be unnecessary if were simply possible to make elements transparent to certain events.

For example, if you make the item you're currently dragging transparent to the mouseover event, then when you drag it over a target element, that element's mouseover event will fire.

That's all you really need to do drag+drop - ie. know over which element the item was dropped.

45 Posted by zm on 23 September 2009 | Permalink

There are only two lines in this post which have a substratum of truth in it:
"Fuck you, Safari team. Fuck. You." and "Fuck you anyway." :)
Otherway I think you can't understand a lot about the HTML5 dnd spec. I don't think it's the best as possible and easy to use. But it's not pointless.

46 Posted by Sebastian Markbåge on 23 September 2009 | Permalink

David, you can do this exact thing by using elementFromPoint (taking Opera quirk into account) while temporarily hiding the element. Described in this thread:

http://groups.google.se/group/mootools-users/browse_thread/thread/f89432a1c151a981

This is exactly what I'm doing for my coming MooTools implementation of the DnD APIs.

However, the point of the DnD APIs are not the mouse gestures per say, but the transfer of data. You have security issues and source/target separation to consider. They should really be called Data Transfer APIs.

It's a very different scope from the Drag and Drop APIs implemented in existing JS frameworks.

47 Posted by Antonio Salazar Cardozo on 23 September 2009 | Permalink

And no, knowing the element the item was dropped on is NOT all you have to do for Drag and Drop. The DnD described in HTML5 is used not only for in-browser drag and drop but also for dropping OUTSIDE the browser, which is critical. These APIs are modeled after standard GUI DnD APIs. Look at the way Qt implements DnD, for example, and you will find many clear similarities.

48 Posted by Marcwolf on 24 September 2009 | Permalink

Hi PPK
I have just brought your book (again) after my first copy was 'borrowed' permanently by another developer.. I despise his morals but appreciate his desire to code.
I am sorry you had to go through the DnD debarkle and wanted to thank you for your perserverance, and inventive command of the english language.
To quote "there but through the grace of God go I"
And therefore I leave it to far far better programmers to venture in the treachous swamps that is DnD.
It seems like the concept of DnD is akin to another moniker of the same name "Dungeons and Dragons" except instead of heroic deeds and smiting of demons one is writing code and depatching bugs (hmm.. if I could transpose the user interface of Dungeons and Dragons for my Debugging processes then that would be more entertaining)
But again many thanks for pointing out why DnD (although a lovely concept for desktop applications) is fraught with danger when used in a browser environment.
Yours Sincerely
Marcwolf

49 Posted by Christopher Boomer on 24 September 2009 | Permalink

You finally snapped! How therapeutic was *that*? Thank you (as ever) for trying...

50 Posted by Andrew M on 25 September 2009 | Permalink

This made my night. I didn't have time to read this but had to after the first few sentences. Thanks.

51 Posted by Johan on 29 September 2009 | Permalink

You didn't happen to record yourself while testing this? I'd pay big money to see your facial expressions.

52 Posted by Axel Berger on 4 October 2009 | Permalink

Two cents:
Users may drop anything anywhere at any time, so setting up a default ignoring this and not doing something totally undesirable seems sensible to me. It is similar to clicks being ignored by default and clickability having to be turned on explicitly.
Second:
I try to avoid dragging like the plague, myself. It can trigger dozens of totally different actions and you never know what they'll be, especially if you miss the target by a pixel or two. I totally disagree with Michael Butler #28. The tool to use is FTP and has been for ages. It is simple and easy to understand. All those GUIs put users into a magical mindset, where actions have to be followed by rote learning in mind-numbing detail and the slightest mistake may trigger all kinds of Zauberlehrling effects. Compare that to the C64 era, when programming and using was perceived as something everyone could do, learn and understand.

53 Posted by Mark Kawakami on 8 October 2009 | Permalink

Great analysis. However, I don't think -khtml-user-drag is actually about drag and drop per se. I think it's about controlling how and what the is displayed when the user drags content from the webpage to elsewhere using the OS' drag-and-drop capabilities (for instance, dragging some selected text into a text editor). I may be wrong about this, but based on some experimenting I did earlier, that was the impression I got.

54 Posted by Cables on 13 October 2009 | Permalink

If only it were that easy. As it turns out, default behavior is sometimes to drag (as when you have already selected text). In my experiments this business of preventing default became quite frustrating, as sometimes you want to stop drags but not selection, or vice versa, but end up stopping both.

The correct way to do this is to allow the programmer to start a drag. As it stands, it is impossible to do things such as only allow vertical drags and not horizontal drags since the API is completely declarative and takes place on an element-by-element basis.

55 Posted by Stephen on 4 November 2009 | Permalink

Imo, the bubbling behavior of drag events isn't a bad thing, it enables other scenarios, you can replicate mouseenter/out events by scanning the relatedTarget, the failing with drag events is relatedTarget is NULL, the spec just says 'it should be null', not why it should be null. er, lovely..

56 Posted by Frank on 13 November 2009 | Permalink

this must have been one of the funniest articles regarding a mundane topic .. i have read ... uhmm: EVER! awesomest! thx 4 that!