9 ms·
The HTML5 drag and drop disaster (2009)
- onion2k 12y agoThis is from 5 years ago.
- striking 12y agoUpdated the title to reflect that, thanks. Really makes you wonder though; why hasn't HTML5 Drag and Drop been simplified yet? I personally have no idea what to do, besides adding JQuery.
- dubcanada 12y agoIt has been, lots of things have been added since 2009 to fix most of his problems.
- striking 12y agoI wasn't aware of this. Do you have any reading material I could look at (as I'm attempting to implement DnD in an app of my own right now)?
- jvickers 12y agoI've done some drag and drop programming, but not using the HTML5 API. I may have read that article quite a few years ago, but another problem was that HTML5 was not considered ready for use all those years ago. Recently (well, within the past year or so) I have found clients' requirements have been far less strict in terms of supporting older browsers, so I have been making use of more HTML5 features. I still have not used HTML5 drag-and-drop. The basics of drag-and-drop only take a few lines to implement, but it's important to do extensive testing to find the edge cases. I found (one year ago) there were problems with jQuery UI that stopped me from making full use of it. I wound up using it for the basic dragging - it would reliably tell me mouse move events, clicks, buttons, and the mouse position, but because the droppables system would miss some events I implemented the logic surrounding detecting where the item was being dragged. Basically, whenever the item got moved, a whole bunch of calculations would run to see what object it's positioned over or near, and it's position within whatever object it's over. If you want to do drag-and-drop programming in the browser, I recommend you write some code that allows you to pick up a DIV and drop it elsewhere on the screen. It's not trivial to do the first time, but once you understand the patterns it becomes so much easier. The techniques are useful for other similar things, like creating resize handles.
- striking 12y agoDo you have any code samples I could look at for reference? I'm quite new to the whole HTML/CSS thing, and I work best learning by example.
- jvickers 12y agoIf I did write a code sample and replied here, would you get to see it? I don't think there is a way to send messages on Hacker News, and I don't yet know if you'll get alerted to replies to old posts.
- aikah 12y agowhat he says is still valid,the spec hasnt changed,is broken even or recent browsers such as Chrome ,is complicated and confusing.It's another exemple of half baked spec written by people that are never going to use it,just like app cache. Frankly HTML5 is a disaster(and no , things like WebWorkers or WebSockets are not part of the HTML5 spec before anyone jumps on me). It's just hard to build something robust on weak foundations,but that's lot of client side developpers, making these things work even though specs are just not helping.
- shacharz 12y agoYou're right, but that's the reason I think all browsers have developer channels. So that developers who actually user those API's will test them, report bugs or even stir the specs towards something useful. I know that's the case at least with WebRTC.
- thristian 12y agoI don't think it's fair to blame the HTML5 drag and drop API entirely on WHATWG; my understanding is that it was originally specced years ago as the sanest useful subset of IE6's drag and drop API. It may not be the prettiest thing ever, but it's prettier than how it started out.
- panzi 12y agoSubset? Isn't it more like a super set? IE6 (and above) has no files array that can be read with a FileReader and it only supports the types "Text" and "URL", no support for proper mime types.
- thristian 12y agoI think this is what I was remembering: http://ln.hixie.ch/?start=1115899732&count=1 http://ln.hixie.ch/?start=1115899732&count=1 ...which is to say, IE6 supported more event types and more configurable behaviour than HTML5 supports, but some of those extra features were just too weird, or outright crashed IE, so they didn't make it into the spec.
- moron4hire 12y agoI've seen this naming pattern a couple of times in articles submitted to HN. The "... considered harmful" pattern starts with Dijkstra, "GOTO statement considered harmful"[1]. It doesn't mean "such-and-such feature is implemented incorrectly." It means, "such-and-such feature, even when implemented correctly, gives programmers at large the wrong notions." So, one would say "singletons considered harmful". The entire notion of singletons is wrong. But the entire notion of drag/drop events is not wrong. Just the implementation. [1] It's interesting to read some of the counter-arguments, and reflect on programming language design arguments we have today: http://web.archive.org/web/20090320002214/http://www.ecn.purdue.edu/ParaMount/papers/rubin87goto.pdf http://web.archive.org/web/20090320002214/http://www.ecn.pur..., and Dijkstra's own commentary on the whole ordeal is--as usual--entertaining http://www.cs.utexas.edu/users/EWD/ewd10xx/EWD1009.PDF http://www.cs.utexas.edu/users/EWD/ewd10xx/EWD1009.PDF
- jackweirdy 12y ago> The entire notion of singletons is wrong Could you expand on that? Haven't heard this argument before
- cpitman 12y agoThey are generally misapplied by developers as a sort of global state, usually with the implied belief that "I'll only ever need one of these". This has all kinds of nasty downstream effects. It becomes more difficult to trace the dependencies between classes, since any class can invisibly depend on a singleton. It becomes painful/impossible to replace that dependency in a particular instance, which makes both testing and extension difficult. Dependency injection solves the issue of sharing copies of the same object, without forcing that the object is implemented as a singleton. You can inject a different/extended implementation, and it becomes easy to trace dependencies.
- jimmaswell 12y agoHow does it make it harder to trace class dependencies? Find all references to the singleton. Sometimes you just really need some global state. Have you ever done game development? Unless you want to pass a giant GameState godobject to every single thing. Singletons or static classes: NotificationManager.PushNotification(..), DBManager.Instance.UpdatePosition(..) Singletons are good for when you want a static class but also need some things you can only do with instance classes.
- couchand 12y agoJust built a pretty significant business application with a UI based on HTML5 drag and drop. There were certainly a few quirks, but it was nothing compared to web development in "the old days". Without any library the whole DnD song and dance is implemented as part of a React component that's only about 100 lines of JavaScript. There are two places likely to trip you up. One of them is as mentioned in the original article: it's hard to remember which events need to have their default prevented. At the moment we're calling `preventDefault` in `onDragOver` which is required to identify the element as a drop target, and `stopPropagation` in `onDrop` which I believe is to prevent many browsers' default attempts to navigate to a dropped url-like thing. The other potential pitfall is that, for security reasons, the data can only be read in `onDrop`, not in `onDragOver`. If you have a string id you don't mind being downcased you can just use the hack of sending that through the data transfer types (eg. as type "id/12345"), with a "text/plain" fallback.
- dm2 12y ago@striking: Does this work for you? http://www.html5rocks.com/en/tutorials/dnd/basics/ http://www.html5rocks.com/en/tutorials/dnd/basics/ http://html5demos.com/drag http://html5demos.com/drag I don't understand why this is an issue, there are tons of great tutorials: https://www.google.com/search?q=HTML5+drag-and-drop https://www.google.com/search?q=HTML5+drag-and-drop Step 1 to being a web developer, search Google first. More than likely anything you need done has been done 10,000 times and there are at least 100 tutorials. Don't be afraid to use libraries such as jQuery,which HTML5 drag-and-drop doesn't require, but I see that you mentioned avoiding it in another comment. Libraries many times also have the advantage of increasing browser support transparently, which is generally a good thing. Worried about loading time with libraries? Use a CDN such as http://cdnjs.com/ http://cdnjs.com/, most users will have the popular ones already cached in their browser. Use StackOverflow if you have questions, that's what it's there for. Hacker News is for... news.
- sfvisser 12y ago> I don't understand why this is an issue, there are tons of great tutorials: ... > Don't be afraid to use libraries such as jQuery, ... So, bad specs are not an issue because there are tutorials explaining how to use them and there are slightly better abstractions on top of them?
- deleted 12y ago[deleted]
- striking 12y ago* I looked into those, but wow wow wee wow are they complex. I'll be working with cloning/moving DIVs instead, especially because HTML5 isn't supported everywhere. * I prefer to avoid libraries when possible, especially when diametrically opposed ones are in use (I'm making an Angular app, JQuery doesn't always play nice). * Thank you for the tip about http://cdnjs.com/ http://cdnjs.com/, I'll be using it in the future. * Hacker News is news, but it's also about discussion. That and I've personally never heard of how bad HTML5 DnD was, I thought the community might benefit from looking into it too.
- 12y ago
- InfiniteRand 12y agoHonestly, if I were still a web developer, I would still use a library. The libraries greatly simplify things for the standard use cases. If I could not use a library, I would look for the unminified code of a library and copy and paste it the relevant section. Because ultimately, unless things go wrong and I need to dig deep, I have better things to do than mastering yet another complex web api.
- Someone1234 12y agoNothing you said is incorrect, nor do I behave differently (who doesn't utilise JQuery?). That being said; it seems like a copout to ignore glaring issues while waving our collective hands in the air and saying "just use a library to abstract it!" One of the reasons libraries are as popular as they are (particularly JQuery which does "nothing" except provide an abstraction) is because the standards are so weak and cross browser support so incomplete. A lot of people think we're currently in a great place in terms of web-development. I actually disagree. We're still in a bad place, it just so happens that were were in an even worse place previously (e.g. IE6 era). Is there any real motive in the standardisation community or web community in general to make the spec' good enough so JQuery is no longer required by 9/10 websites? Why isn't $('#something').click(); built in yet?
- untog 12y agodocument.getElementById('something').addEventListener('click',function() {}) works on all browsers these days. But we're stuck in our habits. I don't deny that web development is kind of crappy, but it's just in the nature of it - the reason why iOS and Android are easier to develop for is because there's really only one client for them. Personally, I'll take the multiple, open client approach over the closed one any day, warts and all.
- bshimmin 12y agoOne key difference is the jQuery version will gracefully do nothing if "#something" doesn't exist, while yours will throw "TypeError: Cannot read property 'addEventListener' of null".
- fiatjaf 12y agoWhat about this[1] non-jQuery "old script"? Can we use it instead? [1]: http://draggabilly.desandro.com/ http://draggabilly.desandro.com/
- striking 12y agoThis may be precisely what I, personally, needed for my web-app. I'll try it tonight and see how it works out, thanks for the link.
- mraison 12y ago> Web developers MUST NOT (in the sense of RFC 2119) use HTML 5 drag and drop. They should use old-school scripts instead. As far as I remember if you do that (i.e. if you use mousedown, mouseover, etc and move your dragged element accordingly), the result won't be nearly as good as with "native" drag and drop, and you will see the dragged element lagging behind the cursor.
- striking 12y agoThat and sharing state with other windows is nearly impossible whereas HTML5 DnD makes multi-window stuff seamless. But I agree when he says that, as it is, HTML5 DnD is ridiculously difficult to implement properly.
- JoshTriplett 12y agoScripts based on mouse events also can't support drag-and-drop across sites or from non-browser applications, which HTML5 drag-and-drop supports.
- josu 12y agoDo Google, Dropbox and others use the native HTML5?
- ascotan 12y agoI've implemented drag and drop multiple times via jquery event handling and never had lagging issues.
- panzi 12y agoIndeed. I also implemented it by hand once and once I did a bit of event throttling (which jQuery also does) it worked smoothly enough even on a very old Android 3 tablet (in Firefox). And the dragged element has opacity!
- ganarajpr 12y agoIf someone was using angular and wanted to use the native html5 drag and drop, I created a directive for it here https://github.com/ganarajpr/angular-dragdrop https://github.com/ganarajpr/angular-dragdrop if you are interested. There is documentation as well in here : http://ganarajpr.github.io/angular-dragdrop/ http://ganarajpr.github.io/angular-dragdrop/ Having read the blog ( from top to end ) I kind of agree with some of the things that the author says. There are a few edge cases that we need to take care of if using native drag and drop. There is also the not-so-slight issue that it doesnt work on mobile browsers....
- JoshTriplett 12y ago> 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. Mouse events also include mouseover, mouseout, mouseenter, and mouseleave. The start/over/enter/leave events serve useful purposes, notably that you can offer UI cues to the user. For instance, if you drag an image onto an image search page that normally accepts text, the search box can become a giant drop target with "drop image here to search" text. And if you drag a non-image onto the same page, the page can check the MIME type and give the user UI that says that won't work.
- Gracana 12y agoThe author gets into that in "dragthat and dragsomethingelse," where they talk about the problem with dragenter and dragleave behaving like mouseover and mouseout, events which fire many times in situations where you generally don't need them to.
- angersock 12y agoAccording to the bugtracker, took the Firefox folks 4 years (2008-2012) to implement that. Read the rest of the article: there's a lot of other stupid API shit that heavily outweighs any clever little benefits.
- mrec 12y ago> Mouse events also include mouseover, mouseout, mouseenter, and mouseleave Not to mention onclick and ondblclick, which really needs access to the OS-level double-click delay setting if you want it to behave properly.
- shangxiao 12y agoHa I remember this article, it's from a few years ago and is when I started to lose my respect for PPK due to all the cursing and carrying on.
- striking 12y agoI agree, his language is incredibly inflammatory and generally unnecessary. But he's done a really good job of writing up the flaws, so I suppose the tradeoff in this case was worth it.
- iza 12y agoIt really should only be used to drag and drop files from another application. If you just want to move elements around on the page mousedown, mousemove, and mouseup are all you need. I don't think we need a new API for this as it is pretty straightforward to roll your own.
- striking 12y agoBut future devs shouldn't have to "roll their own" when someone's done it before. Why not just rewrite the standard and make it sane? JQuery shouldn't be the de facto JS library, those features should be (and are being) integrated into HTML already.
- aniketpant 12y agoOne of the best and well explained issues with the HTML5 DnD. The specs for DnD are written very well but the implementation is brilliantly fucked up that the only way you are left is to use a library and enjoy the hardwork of someone who spent hours getting smeared in the dirt.
- romaniv 12y agoI still don't get why there it no baseline HTML-only drag-and-drop functionality. It would cover a lot of cases with zero effort from developers: <dragarea group="groupX"> <draggable value="abc"> whatever you want here </draggable> </dragarea> <dragarea group="groupX" name="variableName"> </dragarea> You drag element from first dragarea and get variableName=abc on the server. Multiple values work same was as checkboxes. Fancy events could be added incrementally, later.
- chiubaka 12y agoI didn't read that closely enough to understand exactly what was being said, but it was fucking hilarious.
- panzi 12y agoAbout prevent default: You need to tell the browser that this element will handle the drop/has handled the drop, or it will perform its default operation. What is it's default operation? To load the file/URL that you just have dropped onto the browser window. Or maybe you have multiple drop areas stacked on each other. Should the event propagate to the parent element or not? Ok, why is it done in JavaScript and not simply with dropzone="true"? Because you want to be able to let script logic decide if that drop/dragover event is eaten or not. I stopped reading at some point, but I wonder if the author has ever implemented D'n'D support in any other language. It works very similar to this in I guess most GUI APIs. Maybe that is another reason why it works like that in HTML5?
- eridius 12y agoI sympathize with your argument, but unfortunately it doesn't seem to be correct. Arguably, you should be able to implement just the 'drop' event and call event.preventDefault() in that event to suppress the default behavior of loading the file/URL. I don't see a clear reason why any other event should matter, the actual action that triggers the load is dropping. As for propagation to parent elements, that's not controlled by event.preventDefault(), that's controlled by event.stopPropagation(). I do agree that the author doesn't seem to realize that drag & drop is actually rather complex and that other languages look similar (e.g. large number of events). But the quirks around when you have to call preventDefault() do seem to be legitimate issues.
- panzi 12y agoYeah, in other languages you don't use "preventDefault" but e.g. "acceptProposedAction". So they could have added such an method to the event object. I guess it's a bit of a quick fix thing why Microsoft didn't do that and the w3/whatwg just took that. As to "I don't see a clear reason why any other event should matter". Well, yeah, one could implement it so that only the drop event really matters, but I guess it's done the way it is so it forces the programmer to explicitly handle the dragover event. This way the appropriate mouse icon will be displayed and the user knows what's going to happen when they drop now. Strange situation where I, a Linux user, defend something made by Microsoft. Usually I spew a lot of hate against Microsoft just for committing the crime called Internet Explorer (especially version 8, which I still have to support, bah).
- mereskin 12y agoI made an overview of advanced drag-and-drop features and their support in browsers (with examples): http://mereskin.github.io/dnd/ http://mereskin.github.io/dnd/
- deleted 12y ago[deleted]