Javascript - Dragging a Window

When designing dialog boxes, it is important to provide a way for the user to be able to drag them around the screen. It turns out that this was a significant problem which took several days to solve.

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

One of the problems implementing a drag interface is the extreme lack of useful information. HTML5 Drag and Drop (w3schools) contains a number of examples, but no real description of the api. For instance, the ondragstart Event page includes but provides no help on and the various supported data types. As a result, there is no way to determine what the available options are. The mozilla DataTransfer.setData() page added nothing new. It turns out that most browsers don't care if this is set or not - but Firefox requires it.

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.

Presumably, this technique can be used to pass additional variables as strings - just give each a unique name (data type).

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

For any of these techniques to work, the dragover event must be called to cancel the default action. Since I want to position a dialog box, I attached the event to the main document (ie, the browser window). Without this


Firefox

Browser compatibility is always a major problem. It simply isn't possible to write javascript that works cross browsers unless you have multiple browsers to test on. I use 6 on 2 different Windows operating systems - 2 on XP and 4 on 10. Since that is nowhere near enough, I am pretty sure that my applications fail with other configurations. (Oh well!)

In this case, Firefox has several (that I know of) issues with dragging windows.

These are not show stoppers, but without testing I would not have known.

By the way, none of the other browsers I tested have these "issues".


SetData

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

To be perfectly clear, only Firefox requires that line, Chrome does not care if it is there or not.


Moving the Window

In the other browsers, I move the window using clientX/Y to determine the mouse position within the onDrag event. Unfortunately, that fails in Firefox because there is no way to determine the mouse position. To be explicit, during a drag event As a result, it is not possible to position the window at this time.

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

Only Firefox requires that event propagation is stopped in the drop event. If this is not done, then Firefox will try to open a web page with the same name as one of the div blocks - not always the one that was just dragged.

To be clear, none of the other tested browsers require this.


Ghost image

When dragging a window, most of the browsers display a ghost (partly transparent) image of the window. Using Chrome and Windows XP, the ghost disappears when I use code to move the window during the onDrag event.

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

Just a simple div using HTML 5 drag support. The onDragOver event does nothing. I really don't like the "ghost" object.
Simple div - Position set in *drop* event
Using this, Firefox 47 on Windows 10 tried to open www.mcUISimple_div.com (in other words - www.[the div id].com). This was fixed by adding event.preventDefault() to the drop event.


Simple div with onDrag event

Another simple div using HTML 5 drag support. This time the onDrag event repositions the window using event.clientX/Y. This fails in Firefox because event.clientX/Y is equal to (0,0). All the other tested browsers provide the current mouse position. (Standards are great - too bad there aren't any!)
Simple div - onDrag sets position


Window with Title Bar

This is how I want to use the drag technique - Using a Window with a title bar. This is implemented as a div within a div.
w/ Title Bar
This fails in Firefox


Window with Title Bar - page location for Firefox

This example is identical to "Window with Title Bar" (above) except the clientX/Y is replaced with pageX/Y in an attempt to get this to work with 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!

w/ Title Bar - uses pageX/Y for Firefox
This was modified to test Firefox - it sort of works until the cursor slips out of the title bar


Summary

If the drop event does not disable the defaults, Firefox (and ONLY Firefox) will try to open a new page usually using the ID of the first window on the page, not the window I was trying to move.

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.


Summary of Design Problems

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.


References

With the exception of mozilla's Drag operations, none of these references discussed the various browser issues or differences.


Author: Robert Clemenzi
URL: http:// mc-computing.com / Languages / Javascript / Dragging_a_Window.html