Prev: stop form submit
Next: Math ugliness.
From: Peter Michaux on 15 Feb 2010 20:20 Hi, One of the first browser scripting techniques I worked with years ago was DHTML drag and drop. I've come across and thought about three main techniques to determine when a dragged item is over a drop target. All of the ways have pros and cons depending on the situation. 1) When a drag is in progress, use the native mouseover to know when the mouse cursor enters a drop target element. In order for the native mouseover event to fire, there cannot be either the dragged item or a proxy of the dragged item moving around and under with the cursor. If there is an item like this with high z-index between the cursor and target, then the mouseover event for the target cannot fire because the cursor is always over the dragged item. There can be a dragged item beside the cursor but that isn't very visually pleasing or what the user is accustomed to experiencing. This technique is not so great when dragging in a list. If the cursor is between two <li> elements then it is over the <ul> and so where to show the item will drop? Also deciding if the item will drop above or below a particular <li> or will drop at the end of the list is a bit messy. 2) If the dragged item must look like it is remaining under the cursor during the drag, then there is another strategy I saw a long time ago. Extra transparent elements are created and added to the page directly above (i.e. large z-index) the target zones. If these transparent elements have z-index of 10, then the dragged item has a z-index of 5. That way the dragged item appears to be under the cursor but the mouseover events for the extra elements still fire as there is nothing between the cursor and the extra elements. This is appealing but the setup is expensive adding elements to the page. If the page is scrolling or has scrolling elements the exact placement of the extra elements is tricky as position reporting of the real target elements in the page can be tricky. 3) Another option I have used is when the drag starts to compute regions of the page that are drop targets. When the mousemove event is fired during the drag, the position of the mouse is compared to the computed regions to determine which region currently contains the mouse cursor. Depending how the regions are computed this can be O(n) lookup with every mousemove event or it can be O(1) if the regions are all uniform in size. This does require knowing the positions of the drop targets which can be a problem as mentioned in 2 above. I know this system can be very fast and I've had impressed users that note how fast it is compared to some other slow drag and drop implementations. I don't think I've seen any other way of doing things that might be worth considering. The main concerns are the appearance of the dragged item (under or beside the mouse cursor) and the speed of showing the current drop target for each mousemove. Since the mousemove event fires in quick succession the computation needs to be fast. I've only investigated native drag and drop APIs a little and they didn't seem very useful in terms of making an appealing user experience. I'm curious which of the above methods people here have used and if there are any other techniques worth considering. Thanks, Peter
From: jeff on 15 Feb 2010 21:06 Peter Michaux wrote: > Hi, > > One of the first browser scripting techniques I worked with years ago > was DHTML drag and drop. I've come across and thought about three main > techniques to determine when a dragged item is over a drop target. All > of the ways have pros and cons depending on the situation. > > 3) Another option I have used is when the drag starts to compute > regions of the page that are drop targets. I've had no need for drag and drop on an item, but I have done something very much like option 3 for other uses. On another note, Scriptaculous has resortable lists, http://wiki.github.com/madrobby/scriptaculous/sortable-lists-demo you can drag an item of the list around and it then snaps to the nearest list position. I have no idea how they do that and never had enough desire to look through the code, which is no joy. Under no circumstance do I recommend using Scripataculous. But I do find that bit clever. When the mousemove event is > fired during the drag, the position of the mouse is compared to the > computed regions to determine which region currently contains the > mouse cursor. Depending how the regions are computed this can be O(n) > lookup with every mousemove event or it can be O(1) if the regions are > all uniform in size. This does require knowing the positions of the > drop targets which can be a problem as mentioned in 2 above. I suppose you could always recalculate element positions if the page changes (potentially hard to know), or just periodically re-poll (which I've done), but perhaps it is only necessary to know which target you are closest to? Jeff
From: Peter Michaux on 15 Feb 2010 21:23 On Feb 15, 6:06 pm, jeff <jeff_th...(a)att.net> wrote: > Peter Michaux wrote: > > One of the first browser scripting techniques I worked with years ago > > was DHTML drag and drop. I've come across and thought about three main > > techniques to determine when a dragged item is over a drop target. All > > of the ways have pros and cons depending on the situation. > > > 3) Another option I have used is when the drag starts to compute > > regions of the page that are drop targets. > > I've had no need for drag and drop on an item, but I have done > something very much like option 3 for other uses. > > On another note, Scriptaculous has resortable lists, > > http://wiki.github.com/madrobby/scriptaculous/sortable-lists-demo > > you can drag an item of the list around and it then snaps to the nearest > list position. I have no idea how they do that and never had enough > desire to look through the code, which is no joy. > > Under no circumstance do I recommend using Scripataculous. But I do > find that bit clever. > About three years ago, I read the Scriptaculous drag and drop code and the sortable list code. It was hideous to read and ran very slowly. With only a moderately long list the mousemove behavior became very slow as the computation was very complex. That is when I started looking more seriously into other options. Perhaps the Scriptaculous code has improved by now. Peter
From: RobG on 15 Feb 2010 22:09 On Feb 16, 11:20 am, Peter Michaux <petermich...(a)gmail.com> wrote: > Hi, > > One of the first browser scripting techniques I worked with years ago > was DHTML drag and drop. I've come across and thought about three main > techniques to determine when a dragged item is over a drop target. All > of the ways have pros and cons depending on the situation. [...] > 3) Another option I have used is when the drag starts to compute > regions of the page that are drop targets. When the mousemove event is > fired during the drag, the position of the mouse is compared to the > computed regions to determine which region currently contains the > mouse cursor. Depending how the regions are computed this can be O(n) > lookup with every mousemove event or it can be O(1) if the regions are > all uniform in size. This does require knowing the positions of the > drop targets which can be a problem as mentioned in 2 above. I know > this system can be very fast and I've had impressed users that note > how fast it is compared to some other slow drag and drop > implementations. Have you considered a quadtree[1]? I've never programmed one, but they are commonly used in CAD and other graphics applications dealing with 2d and 3d spatial indexing. The downside is that calculating the index can be slow, but as long as the elements don't move around too much, it shouldn't be an issue. It may not be suitable for the small number of tragets in a typical HTML page. There are optimised forms that might be better, such as R-Tree[2]. 1. <URL: http://en.wikipedia.org/wiki/Quadtree > <URL: http://books.google.com.au/books?id=M2QYbTVd0VgC&pg=PA394&lpg=PA394&dq=quad-tree+lookup&source=bl&ots=K4sZ9EvL0Q&sig=M05iPzjCvPJ7PQ2ZKuuyYHN3y-Y&hl=en&ei=Mgh6S5KGMs2OkQWS_a37Cg&sa=X&oi=book_result&ct=result&resnum=1&ved=0CAkQ6AEwAA#v=onepage&q=&f=false > 2. <URL: http://en.wikipedia.org/wiki/R-tree > -- Rob
From: Peter Michaux on 15 Feb 2010 23:06
On Feb 15, 7:09 pm, RobG <rg...(a)iinet.net.au> wrote: > On Feb 16, 11:20 am, Peter Michaux <petermich...(a)gmail.com> wrote: > > > > > Hi, > > > One of the first browser scripting techniques I worked with years ago > > was DHTML drag and drop. I've come across and thought about three main > > techniques to determine when a dragged item is over a drop target. All > > of the ways have pros and cons depending on the situation. > [...] > > 3) Another option I have used is when the drag starts to compute > > regions of the page that are drop targets. When the mousemove event is > > fired during the drag, the position of the mouse is compared to the > > computed regions to determine which region currently contains the > > mouse cursor. Depending how the regions are computed this can be O(n) > > lookup with every mousemove event or it can be O(1) if the regions are > > all uniform in size. This does require knowing the positions of the > > drop targets which can be a problem as mentioned in 2 above. I know > > this system can be very fast and I've had impressed users that note > > how fast it is compared to some other slow drag and drop > > implementations. > > Have you considered a quadtree[1]? I've never programmed one, but > they are commonly used in CAD and other graphics applications dealing > with 2d and 3d spatial indexing. No I hadn't considered a quadtree but I can imagine it would be useful to keep the number of regions low. Perhaps it would be especially useful if there were circular shaped targets. Thanks for the links. Peter |