a5hik / ng-sortable

AngularJS Library for Drag and Drop, supports Sortable and Draggable. Supports Touch devices.
http://a5hik.github.io/ng-sortable/
MIT License
1.15k stars 314 forks source link

Issues with scrolling on touch #141

Open rburnham52 opened 9 years ago

rburnham52 commented 9 years ago

I'm having a few issues with scrolling not behaving as you would expect.

  1. performing a swipe up / down gets captured by drag and drop. Drag and drop should have a slight delay before triggering a drag so it can detect if the user is swiping (check if the user is scrolling after a short delay). Think iOS moving an app icon. To move an icon you need to hold it for a small amount of time before it unlocks and becomes draggable
  2. While dragging an item if the list is larger than the viewable area it should auto scroll when the item you're dragging hits the sides or the viewable area or constrained container(mainly up or down)

Is it possible to fix either of these issue? if it had these 2 features it would be a really solid options for drag and drop on touch devices.

rburnham52 commented 9 years ago

So i'm thinking about working on this as we require this behaviour. to fit with the no jquery approach i was thinking about how this could be done.

Firstly is there anything in Angular that would provide tap, hold, swipe events? If not then i guess i dig into how jQuery mobile handles this and try to reproduce it.

Any thoughts?

a5hik commented 9 years ago

@nitro52 right now we are capturing the touch events by binding (touchstart, touchmove, touchend, touchcancel) to the element.

the touch action is validated here. sortable-helper.js 'isTouchInvalid' . It validates If it is a touch or a tap.

This could be the place to look for.

rburnham52 commented 9 years ago

where is sortable-helper.js? is this an angular dependency? I can't seem to find it. Sorry i'm still pretty new to angular.

a5hik commented 9 years ago

@nitro52 its this library code only and you can see in the source of this plugin.

rburnham52 commented 9 years ago

I got it working as i mentioned, just needs a bit of clean up. I tried to merge my changes with the latest version but now its broken drop because of this issue

https://github.com/a5hik/ng-sortable/issues/139#event-281807474

So i need to wait on a fix for this before i can test it properly. Things to note. I tried using the scrollableContainer variable to determine what to scroll but setting its scrollTop did not update anything. So for now i'm just scrolling the window. But this could be an area for improvement.

morious commented 9 years ago

@nitro52 , where are you standing with this? I am running into the same issue and need to be able to delay the drag a bit so that scroll kicks in. any ideas?

Jeevanandanj commented 9 years ago

Hi actually this is awesome library. But me too have the same kind of issue. Is there any possibility to disable the drag and drop in touch devices.

gareys commented 9 years ago

Similar issue with scrolling on mobile: https://github.com/a5hik/ng-sortable/issues/98

KammererTob commented 8 years ago

I have a somewhat desireable solution to the scrolling problem on mobile devices:

I am using a seperate movement listener for touch movements like this:

angular.element($document).bind('touchmove', touchMoveListen);

with the function defined as:

            var startTime = performance.now();
            var touchStart = {clientX: $helper.eventObj(event).clientX, clientY: $helper.eventObj(event).clientY};
            var touchMoveListen = function(e) {
              var eventObj = $helper.eventObj(e);
              var currentTime = performance.now();
              // If the movement in y-direction is still below the threshold and
              if ((currentTime - startTime) > 100 && Math.abs(eventObj.clientY - touchStart.clientY) < 20 && Math.abs(eventObj.clientX - touchStart.clientX) < 40) {
                e.preventDefault();
                unbindMoveListen();
                dragStart(event);
              } else {
                unbindMoveListen();
              }
            };

Explanation: I am just checking if the touch was longer than a specificed time (100ms, but this is tuneable) and also how far the "finger" moved in this timespan. If it stayed in near proximity (here 20px in both directions) we assume that the finger stayed on a dragable item and wants to move it. Otherwise we assume that the user wants to scroll and thus we unbind all move listeners.

I am open for suggestions and hope that this helps.