SortableJS / Sortable

Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.
https://sortablejs.github.io/Sortable/
MIT License
29.72k stars 3.7k forks source link

Doesn't work on iPhone, iPad #1319

Open rgamage opened 6 years ago

rgamage commented 6 years ago

I just tried the demo page on my iPhone 6, and iPad (latest generation), using Safari and it didn't work on either one. Dragging caused very jerky scroll motion of the whole page, so both the item and the whole page are moving, and the item that you drag floats quite a ways away (several inches), like there is some offset issue. Does this work for anyone else on iPhone/iPad devices?

anschutz commented 6 years ago

Can confirm that it doesn't work on iOS Safari and Chrome after updating to iOS 11.3.1. It seems that the default is not prevented and the page is scrolled along with the draggable item

branko2712 commented 6 years ago

Same problem as described, whole page is moving by trying to sort items on page.

Equipment: Iphone SE, using Safari browser...

anschutz commented 6 years ago

You can quickly solve it yourself by defining your own touchstart event handler on a drag handle (our the whole draggable if there's no handle) to prevent default. That's enough to prevent it from being scrolled natively.

branko2712 commented 6 years ago

Your idea works, thanks a lot @anschutz ! 💯 👍 🥇

leekashun commented 6 years ago

@branko2712 ,can have any example code?

i have added following code to prevent default, but not working.

$(".my-handle").on('touchstart',function(event) {event.preventDefault(); }, false);

branko2712 commented 6 years ago

@leekashun

Hello, I've used this code:

disableHandle() {
    let listToDisable = document.querySelectorAll('.handleGroupDrag'); //needed for IOS devices on Safari browser (FIX)
    if (listToDisable) {
        listToDisable.forEach(item => {
            item.addEventListener('touchstart', (event) => {
                event.preventDefault();
            })
        })
    }
}

It is bit complicated since I have multiple nested sortable containers so I had to get all of them and prevent default event on each and every in that list. Also I'm working with ReactJS so here you can see that I used arrow functions (ES6 feature), don't be confuse about that...

hanc2006 commented 6 years ago

Add this code on your page, it is also useful for solving the sticky :hover issue on mobile devices.

(function(l){var i,s={touchend:function(){}};for(i in s)l.addEventListener(i,s)})(document);

The plugin option to prevent scroll on mobile device doesn't work even if set.

scroll: false

If you want lock the page while moving the elements you have to add these events:

onStart: function() { document.ontouchmove = function(e) { e.preventDefault();  }}
onEnd: function() { document.ontouchmove = function(e) { return true; }}

I hope you find it useful