Opened 9 years ago
Last modified 6 years ago
#9635 open bug
Sortable: Item flying off screen with revert=true
Reported by: | the-razer | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | none |
Component: | ui.sortable | Version: | 1.10.3 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
Hi,
When you're dropping a list item on a scrolled page, the item flies off screen by the distance you scrolled down and then returns to the placeholder. Here's a showcase: http://jsfiddle.net/DZ6x4/
I have this bug at least with current Firefox and IE. I use jQuery 1.9.1 and jQuery-UI 1.10.3, the JSFiddle has different versions but it's the same problem (I was not able to include it otherwise, sorry).
It seems that changing in jquery.ui.sortable.js:
if ( !axis || axis === "y" ) { animation.top = cur.top - this.offset.parent.top - this.margins.top; // + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); }
to:
if ( !axis || axis === "y" ) { animation.top = cur.top - this.offset.parent.top - this.margins.top; }
solves this for me, but I have no clue if that's really the problem or if I'm using it the wrong way.
Change History (5)
comment:2 Changed 9 years ago by
Status: | new → open |
---|
Thanks the-razer.
You don't need a placeholder to duplicate the issue - http://jsfiddle.net/NnQAm/. This is possibly a duplicate of #5039.
comment:3 follow-up: 5 Changed 9 years ago by
I too see this issue although I have a complex situation where a sortable ul element is inside an absolutely positioned, scrollable parent that is not the document body. This situation has been discussed at length in many places and none of the solutions provided have worked for me. Upon deeper inspection it turns out to be variable initialization issue in ui.sortable. Below shows lines 12210-12222 from the combined jquery-ui-1.10.4.js library.
$.extend(this.offset, { click: { //Where the click happened, relative to the element left: event.pageX - this.offset.left, top: event.pageY - this.offset.top }, parent: this._getParentOffset(), relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper }); // Only after we got the offset, we can change the helper's position to absolute // TODO: Still need to figure out a way to make relative sorting possible this.helper.css("position", "absolute"); this.cssPosition = this.helper.css("position");
_getParentOffset() is used to calculate this.offset.parent.top which is critical to correctly (vertically) positioning an item being dragged. The _getParentOffset in turn used relies on this.cssPosition to be "absolute" in this situation. Unfortunately this.cssPosition is not initialized until after the call to _getParentOffset so is.offset.parent.top is calculated incorrectly the first time an item is dragged. I hope this provides insight into the issue. I will also work on providing a fiddle as an exemplar.
comment:4 Changed 7 years ago by
After this many months, this bug still appears in Internet Explorer 11. http://pastebin.com/LRsyma59
Would be nice if a permanent fix was available. :(
comment:5 Changed 6 years ago by
Replying to colin.mccabe:
I too see this issue although I have a complex situation where a sortable ul element is inside an absolutely positioned, scrollable parent that is not the document body. This situation has been discussed at length in many places and none of the solutions provided have worked for me. Upon deeper inspection it turns out to be variable initialization issue in ui.sortable. Below shows lines 12210-12222 from the combined jquery-ui-1.10.4.js library.
$.extend(this.offset, { click: { //Where the click happened, relative to the element left: event.pageX - this.offset.left, top: event.pageY - this.offset.top }, parent: this._getParentOffset(), relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper }); // Only after we got the offset, we can change the helper's position to absolute // TODO: Still need to figure out a way to make relative sorting possible this.helper.css("position", "absolute"); this.cssPosition = this.helper.css("position");_getParentOffset() is used to calculate this.offset.parent.top which is critical to correctly (vertically) positioning an item being dragged. The _getParentOffset in turn used relies on this.cssPosition to be "absolute" in this situation. Unfortunately this.cssPosition is not initialized until after the call to _getParentOffset so is.offset.parent.top is calculated incorrectly the first time an item is dragged. I hope this provides insight into the issue. I will also work on providing a fiddle as an exemplar.
This is exactly what I have found. The first time you drag an element after sortable is constructed, the positioning is wrong. But after the first time it works because cssPosition = 'absolute'
.
There is a simple work-around. set cssPosition to 'absolute' right after construction, before the user has a chance to drag an element.
$('.my-sortable').sortable({ /* options to construct the sortable */ }); $('.my-sortable').sortable('instance').cssPosition = 'absolute';
Tested on jQuery UI Sortable 1.12.1
the original code is of course:
and I seem to have messed up JSFiddle. Here's the correct link now: http://jsfiddle.net/DZ6x4/6/
That's my first time reporting a bug, so please bear with me