Repository navigation
Conversation
When the app removes the dragged element while a fallback (touch or forceFallback) drag is in progress, _emulateDragOver throws "Cannot read properties of null (reading 'Sortable...')" every 50 ms until the pointer is released, and nearestEmptyInsertDetectEvent puts the removed element back into a nearby empty list, so the drop reports an add/remove for an element the app no longer has. Both now skip the drag once dragEl has no parent. The drop that follows ends it as before. SortableJS#2307
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses the error in #2307. It does not add the cancel API that issue also asks for.
The problem
Frameworks own the DOM of a list, so they can remove the element that is being dragged: a re-render after the data changed, an item deleted by another user, and so on. During a fallback drag (any touch drag, or
forceFallback: true) Sortable then breaks in two ways:_emulateDragOverruns every 50 ms and readsdragEl.parentNode[expando]. WithdragEldetached, it throwsTypeError: Cannot read properties of null (reading 'Sortable...')on every tick until the pointer is released.nearestEmptyInsertDetectEventstill runs ontouchmove/mousemove. When the pointer gets near an empty list, it calls_onDragOver, which appends the removed element to that list. On release, Sortable firesonAdd/onRemovefor an element the app has already deleted, and the element stays in the DOM untracked by the framework.We hit this in a Blazor app on Android. When an item is dropped into another list, the Blazor wrapper puts the DOM back the way it was and tells .NET, and .NET re-renders a moment later. A user who grabs the item again inside that window loses it mid-drag.
Reproduction
tests/empty-list.htmlwithforceFallback: true, plus a timer that removes the chosen item:Start dragging an item from list1 and keep holding it. After 3 seconds the console starts logging the TypeError. Now move over the empty list2 and the removed item appears in it. Release, and
onAddfires for it.The change
Both entry points now skip the drag once
dragElhas no parent. Nothing is left to sort, and the drop that follows ends the drag the way it does today:index(dragEl)is -1, so no add/remove/update events fire and_nulling()resets the state. The native HTML5 drag path is unchanged.Test
I added a test in a new
Dragged element removedfixture onempty-list.html. It starts a touch-type pointer drag, removes the item, then moves over the empty list and releases. It asserts that there are no errors and that the item was not inserted back._emulateDragOver._emulateDragOverguard it fails on the re-insertion.npm run build:umd && npm test(headless Chrome). The build output is not committed, as CONTRIBUTING asks.