I have a list that is sortable via drag and drop. It works perfectly on desktop browser, and on Chrome on Android. However, it didn't work at all on Safari and Chrome on iOS 12.1.2 (iPhone 8).
See snippet below, and also for easy mobile testing: https://codepen.io/Kelderic/pen/KJMRgb
var dragging = null;
document.addEventListener('dragstart', function(event) {
var target = getLI(event.target);
dragging = target;
event.dataTransfer.setData('text/plain', null);
event.dataTransfer.setDragImage(self.dragging, 0, 0);
});
document.addEventListener('dragover', function(event) {
event.preventDefault();
var target = getLI(event.target);
var bounding = target.getBoundingClientRect()
var offset = bounding.y + (bounding.height / 2);
if (event.clientY - offset > 0) {
target.style['border-bottom'] = 'solid 4px blue';
target.style['border-top'] = '';
} else {
target.style['border-top'] = 'solid 4px blue';
target.style['border-bottom'] = '';
}
});
document.addEventListener('dragleave', function(event) {
var target = getLI(event.target);
target.style['border-bottom'] = '';
target.style['border-top'] = '';
});
document.addEventListener('drop', function(event) {
event.preventDefault();
var target = getLI(event.target);
if (target.style['border-bottom'] !== '') {
target.style['border-bottom'] = '';
target.parentNode.insertBefore(dragging, event.target.nextSibling);
} else {
target.style['border-top'] = '';
target.parentNode.insertBefore(dragging, event.target);
}
});
function getLI(target) {
while (target.nodeName.toLowerCase() != 'li' && target.nodeName.toLowerCase() != 'body') {
target = target.parentNode;
}
if (target.nodeName.toLowerCase() == 'body') {
return false;
} else {
return target;
}
}
ul.sorting {
padding: 0;
margin: 0;
list-style: none;
max-height: 300px;
overflow-y: auto;
box-shadow: inset 0 0 3px 1px rgba(0, 0, 0, 0.2);
}
ul.sorting li {
padding: 10px;
border-bottom: 1px solid black;
user-select: none;
cursor: move;
}
ul.sorting li:last-child {
border-bottom: none;
}
<ul class="sorting">
<li draggable="true" style="user-drag:element;">List Item 15</li>
<li draggable="true" style="-webkit-user-drag:element;">List Item 2</li>
<li draggable="true" style="-webkit-user-drag:element;">List Item 3</li>
<li draggable="true" style="-webkit-user-drag:element;">List Item 4</li>
<li draggable="true" style="-webkit-user-drag:element;">List Item 5</li>
<li draggable="true" style="-webkit-user-drag:element;">List Item 6</li>
<li draggable="true" style="-webkit-user-drag:element;">List Item 7</li>
<li draggable="true" style="-webkit-user-drag:element;">List Item 8</li>
<li draggable="true" style="-webkit-user-drag:element;">List Item 9</li>
<li draggable="true" style="-webkit-user-drag:element;">List Item 10</li>
<li draggable="true" style="-webkit-user-drag:element;">List Item 11</li>
<li draggable="true" style="-webkit-user-drag:element;">List Item 12</li>
</ul>
https://i.sstatic.net/UDyXF.jpg (Size is too large for direct embed)
Why is this not working on iOS? I can't even get the dragstart
event to fire. On Android Chrome, a longpress fires the dragstart
.
My fallback idea is to make a longpress using touchstart
and touchend
, then create my own absolutely positioned ghost element and drag it around manually. That is a lot of extra code when the drag*
events should just work.
Am I missing something?
LI elements in mobile Safari have an ondragstart
event as part of their prototype. The question is getting it to fire.
Also, according to caniuse, mobile Safari should support this. However, caniuse also shows Android Chrome as not supporting, which isn't true.
I have done a lot of research over the past week on this topic, and I've done a lot of testing and debugging. What I have discovered is that iOS supports drag events, but iOS doesn't trigger them. (As of iOS 12)
If you test webpage on iOS Safari, you'll see that all HTML elements have ondragstart
attached to their prototype. The drag events are all there. They just never get triggered.
Others have run into this issue as well. Event Modernizer doesn't detect Drag and Drop support because of this false support.
Additionally, I dug through the Safari docs, and found this:
iOS Note: Although drag and drop are not supported, you can produce...
It says "supported", but immediately below, there is an event table, which shows drag
and says that it isn't "Generated".
This means that caniuse is currently wrong, and needs updated.
The code is not working solely because Apple has chosen not to trigger drag events.