Determining Offsets with Scrolling Overflow
In drag and drop situations, there's often a time where an area of the page is within an element with the overflow set to scroll. This is common to display a list of items that would be longer than the rest of the elements on the page. If you're dragging from Section A to Section B, you don't want the user to have to scroll down the page to access the drop point. JPG Magazine is a prime example of that (see Figure 1).
Figure 1. The scroll area from JPG Magazine.
With JPG Magazine, the elements can be dragged from the left and dropped within the list on the right. The list of "themes" is quite long and is therefore placed within a scrollable section using
When the user drags the image over, the site needs to accurately know which theme you happen to be dropping the photo on. As described in Determining the Droppable, this is done by calculating the
offsetLeft of the elements all the way up the tree (see Quirksmode for an example script). We have to go all the way up the tree because the offsets are only relative to the positioned parent element.
In the example, the "Fluid" element might have an offsetTop of 200px which would be 200 pixels from the top of the element that has
overflow:scroll set on it. It does not take into account the fact that the parent element has been scrolled. Therefore, the cursor's position which is relative to the offset of the in relation to the total offset of the "Fluid" element won't match.
scrollTop and scrollLeft
If a parent element has been scrolled, you can use the scrolled elements's
scrollLeft properties. Therefore, to calculate an element's real position, you need to total up the total offsets and take away any scrolling offsets. Whether you have to determine whether the page has scrolled or not depends on whether you can determine whether the mouse or element position is relative to the top-left of the document or to the window.
offset) and YUI (using
getXY) do this automatically whereas Mootools and PrototypeJS require more explicit direction to include the offset.
Mootools requires you to pass in an array of elements that may have scrolling when using
getPosition. PrototypeJS has
realOffset to calculate the scroll offset separately.
For a look in the drag and drop process, check out: