P
Peter Michaux
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
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