Skip to main content

Search and Top Navigation

#9544 open bug ()

Opened September 09, 2013 10:36AM UTC

Last modified August 24, 2014 11:27AM UTC

draggable invalid reverts to original mouse position, not true original position - problem with fixed elements

Reported by: alhammer Owned by: alhammer
Priority: minor Milestone: none
Component: ui.draggable Version: 1.10.3
Keywords: Cc:
Blocked by: Blocking:
Description

If you have a fixed parent container, with draggable elements, and you drag them with a helper outside of this parent, and scroll down the page, and have "revert: invalid", it will revert to positions based on the original mouse position of the, and not the actual original position of the original container. Since the container element is fixed, this mean it "moves" down along with the page, but the element reverts to a different position where the fixed element was when "_mouseStart" occurred.

It is easy to fix this, if the helper is a clone just make the originalPosition update based on the original elements offset() instead of original mouse position. If the helper is not a clone, it's not possible to fix in the current way reverted positions are calculated. It only affects fixed/sticky position elements or elements that have changed position via DOM Manipulation/Animations.

I did this:

revert : function(event) {

	$(this).data("ui-draggable").originalPosition = $(this).offset();

	return !event;
}
Attachments (0)
Change History (6)

Changed September 09, 2013 10:53AM UTC by alhammer comment:1

I created a fiddle: If you notice the blue box (with default behavior) doesn't revert back when scrolled beyond the fixed container. The green box, however, with my fix, reverts to its original position.

http://jsfiddle.net/J2HJD/1/

Also: notice how after trying to scroll down once, and you "revert" and then you start to drag for a second time, it starts way below the page: this shouldn't happen. It thinks the fixed element is not where it actually is. This happens for both elements (even my fix!) Probably has something to do with caching positions as opposed to updating the positions on each mouseStart/mouseStop event.

Changed September 10, 2013 01:24AM UTC by tj.vantoll comment:2

owner: → alhammer
status: newpending

Hi alhammer,

Thanks for taking the time to contribute to the jQuery UI project. This behavior only occurs when you set the

appendTo
option so that the draggable is outside of the fixed container. In your case you're using
appendTo: "body"
.

Is there any reason you need the helper appended outside of the fixed container?

Changed September 10, 2013 07:21AM UTC by alhammer comment:3

status: pendingnew

Yes. I am working on an HTML5 web game, and on the right column of the website is a fixed UI that contains a users "backpack" with an overflow: auto property. They can then drag items outside of the fixed backpack div to various different places in the game (equip slots to equip armor, trash icon to delete, to your avatar to use potions/etc.).

If I remove the appendTo, I am no longer able to drag the items out of the backpack, as it gets stuck in the "fixed UI".

Changed September 10, 2013 01:38PM UTC by tj.vantoll comment:4

status: newpending

Replying to [comment:3 alhammer]:

Yes. I am working on an HTML5 web game, and on the right column of the website is a fixed UI that contains a users "backpack" with an overflow: auto property. They can then drag items outside of the fixed backpack div to various different places in the game (equip slots to equip armor, trash icon to delete, to your avatar to use potions/etc.). If I remove the appendTo, I am no longer able to drag the items out of the backpack, as it gets stuck in the "fixed UI".

I'm not seeing this. If I remove

appendTo
on your test case everything seems to work fine http://jsfiddle.net/tj_vantoll/VcY9j/. Am I missing something?

Changed September 14, 2013 08:05AM UTC by alhammer comment:5

status: pendingnew

http://jsfiddle.net/VcY9j/1/

Sorry, I should have specified more: If you notice, I updated it and added an overflow: scroll; This means the element cannot leave the container, which means the container must be the body. This is necessary because my element is a scrollable fixed width/height panel with items inside of that. Users need to be able to drag items out of it and on to else where.

So the bug is very specific, but it's a use case I can see popping up, especially for UI/HTML5 Games:

Draggable elements, in container with "overscroll: auto/scroll", appended to the document, with invalid: revert, does not revert to the fixed container. This is because in the jqueryui code, it "caches" the "original" position, instead of calculating it on the moment of "revert".

Changed August 24, 2014 11:27AM UTC by mikesherov comment:6

status: newopen

http://jsfiddle.net/VcY9j/3/ shows the issue.

to repro:

1. drag blue box out.

2. while dragging, scroll the page

3. let go.

4. observe that it reverts to the offset at the beginning, not the current position.