This page presents several design approaches using the HTML 5 drag events and explains the problems (that I know of) with each. Implementing this capability using regular mouse events (and their related problems) is described on this page.
All the examples I found drag something from one container to another. For a dialogbox, I want to drag from one position to another. In other words, the entire screen is the target container.
Using normal mouse events, the motion was ok (a bit choppy, not real smooth) but sometimes the mouse would slip out of the div and begin highlighting the text on the page. I eventually fixed that by temporarily adding another div that covered the client and having the mouse move over it while repositioning the window under it - but what a pain.
In theory, using the HTML 5 provided drag interface should produce a cleaner and simpler implementation. I never got the plain vanilla drag to work - probably because the tutorials I found are pretty worthless and because they wanted to move components from one container to another. I also did not like the blurred out ghost that was dragged around.
By combining the mouse technique to set the window position and drag interface calls, I was able to get a good smooth drag (but only in Chrome). Unfortunately, sometimes the component would just jump to the upper left - obviously a browser design problem. With a bit of code to test for a negative top, I was able to kludge the problem and get a working solution. I eventually discovered that the trick was to disable the default event action when the component was dropped - but more about that later.
Unfortunately, in Windows 10, the ghost came back for several (not all) browsers. As a result, I use the more generic (and slightly messier) mouse events to implement drag functionality.
Drag interface
document.addEventListener("dragstart", function(event) { // The dataTransfer.setData() method sets the data type and the value of the dragged data event.dataTransfer.setData("Text", event.target.id); }); |
event.dataTransfer.setData() |
A discussion of various options was found at Recommended Drag Types, but the option I wanted was specific to mozilla only.
Via trial and error, and a bit of reading between the lines, the following combination allows a text string to be set when the drag operation begins and then made available at a later time.
function SimpleDragstart(event){ event.dataTransfer.setData("text/plain", event.target.id); } document.addEventListener("drop", function(event) { event.preventDefault(); var data = event.dataTransfer.getData("text"); }); <div id=mcUISimple_div draggable="true" ondragstart="SimpleDragstart(event)" ondrag="SimpleDrag(event)" >Simple div </div> |
Apparently, the drop event does nothing - you have to write the appropriate code. The examples (I found) all move a selected div from one parent to another. I want to move a window (div) from one location to another. Therefore, I need to add that code myself. In fact, this is no different than the code I developed for my "mouse events only" implementation.
The only other problem is - What to do during the drag operation?
This is where the drag technique falls apart - I was never able to generate an acceptable (to me) result!
drop
document.addEventListener("dragover", function(event) { event.preventDefault(); }); |
Firefox
In this case, Firefox has several (that I know of) issues with dragging windows.
By the way, none of the other browsers I tested have these "issues".
I originally developed a simple solution for Chrome 49 on Windows XP. Unfortunately, that solution completely failed using Firefox 45 with Windows XP. The start drag event would fire, but none of the others. To get the ondrag event to fire, the ondragstart event had to contain
event.dataTransfer.setData("text/plain", event.target.id); |
Moving the Window
Instead, I had to add code (via a pointer) to the onDragOver event attached to the document since both sets of mouse positions are available there.
Unfortunately, this did not really fix the problem - while it is now possible to move the window, the cursor keeps slipping out of the title bar (even in Chrome). In my opinion, this IS a show stopper. Because of Firefox's truly crappy implementation, the HTML 5 drag interface has no value.
drop event
document.addEventListener("drop", function(event) { event.preventDefault(); // seems to have no effect except in Firefox // without this, Firefox tries to open a new page }); |
To be clear, none of the other tested browsers require this.
Ghost image
Unfortunately, using Windows 10, I was not able to hide the ghost. As a result, the drag functionality has absolutely no value (to me, at least).
Simple div
Simple div with onDrag event
Window with Title Bar
Window with Title Bar - page location for Firefox
That's when I discovered that onDrag won't work with pageX/Y either. As a result, I moved the code to onDragOver (which makes the mouse position available).
It helped - a little - but is still pretty worthless. The mouse cursor simply won't stay locked to the title bar. This even fails in Chrome!
OS | Browser | Simple | Simple w/ Drag | w/ Title Bar |
---|---|---|---|---|
Win XP | Chrome 49 | Shows a ghost when dragging | No ghost, looks good | Good |
Firefox 24 | Shows a ghost when dragging then tries to open new page | Won't move because dataTransfer.setData() is not called | Won't move because dataTransfer.setData() is not called | |
Win 10 | Chrome 55 | Shows a ghost when dragging | Shows a ghost and the window - worthless | Shows a ghost and the window - worthless |
Firefox 47 | Shows a ghost when dragging | Won't move - tries to open new page | Won't move - tries to open new page | |
Edge 25 | Moves - uses a copy, not a ghost | Very hard to move - unacceptable | Smooth move, but 2 title bars - worthless | |
IE 11 | Ghost, does not move | Will move a few pixels and stop, no ghost | Works |
The window modified to test Firefox is not included in the table because it is about the same as other window with the title bar in all the other browsers. In Firefox, it almost worked - it dragged for a bit, and then the cursor would leave the window. Not a significant improvement - pretty worthless overall.
Unfortunately, when Firefox calls the ondrag event, the event object does not contain any mouse position information. As a result, the onDragOver event must be used to get that information. Otherwise, there is no way to correctly position the component. However, that does not fix the problem since the cursor keeps slipping out of the title bar.
To be perfectly clear - the Firefox drag implementation is the same in Windows 10 as Windows XP. As a result, there is NO WAY to ever support dialog boxes in Firefox using the "built-in" HTML 5 drag-and-drop interface!!!
When setting breakpoints in Firefox, the mouse gets into a state where you can no longer click on anything. In windows XP, the solution is to right click on one of the application icons at the bottom of the screen. That resets the cursor so that the mouse is usable. Simply changing screens (applications) via Alt-Tab does not work because the old mouse cursor is simply cached and restored. Clicking on an application icon keeps the "mouse is not available" icon from being restored. Unfortunately, in Windows 10 - you're screwed. I was not able to find a way to recover the mouse (though sometimes F5 works).
To be blunt - Firefox sucks.
Once, while debugging on Windows 10 - suddenly, in all 4 browsers - none of the ondrag events could be called. Since the code was working perfectly with Chrome on Windows XP, the obvious problem was something wrong (hung) with Windows 10. In fact, I couldn't drag any of the desktop icons either. What a crappy operating system. I "switched users" and that "fixed" the problem - but it also rearranged all the icons on the desktop (which is why the desktop is mostly worthless). The bottom line is that - Debugging drag events in Windows 10 will sometimes hose the operating system.
Chrome on Windows 10 has a ghost of the window showing when I move any of the windows. There is no obvious way to get rid of this. On Windows XP, most of the time there is no ghost and the drag function works perfectly. However, there are occasional ghost problems.