And*_*cer 7 html javascript webkit drag-and-drop ios
我有一个可通过拖放进行排序的列表。它可以在桌面浏览器和 Android 上的 Chrome 上完美运行。但是,它在 iOS 12.1.2 (iPhone 8) 上的 Safari 和 Chrome 上根本不起作用。
请参阅下面的代码段,也可以方便地进行移动测试: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;
}
}Run Code Online (Sandbox Code Playgroud)
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;
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
https://imgur.com/a/I8hzPxC(尺寸太大无法直接嵌入)
为什么这不适用于 iOS?我什dragstart至无法触发事件。在 Android Chrome 上,长按会触发dragstart.
我的后备想法是使用touchstartand进行长按touchend,然后创建我自己的绝对定位的幽灵元素并手动拖动它。当drag*事件应该正常工作时,这是很多额外的代码。
我错过了什么吗?
移动 Safari 中的 LI 元素将ondragstart事件作为其原型的一部分。问题是让它着火。
此外,根据 caniuse 的说法,移动版 Safari 应该支持这一点。但是,caniuse 还显示 Android Chrome 不支持,这是不正确的。
过去一周我对这个主题做了很多研究,并且做了很多测试和调试。我发现iOS支持拖动事件,但iOS不会触发它们。(从 iOS 12 开始)
如果您在 iOS Safari 上测试网页,您将看到所有 HTML 元素都已ondragstart附加到其原型。拖动事件都在那里。他们只是永远不会被触发。
其他人也遇到了这个问题。由于这种错误支持,Event Modernizer不会检测到拖放支持。
此外,我仔细研究了 Safari 文档,发现了这一点:
iOS 注意:虽然不支持拖放,但您可以生成...
它说“支持”,但紧接着下面有一个事件表,显示drag并表明它不是“生成”。
这意味着caniuse目前是错误的,需要更新。
该代码不起作用仅仅是因为 Apple 选择不触发拖动事件。
小智 6
我在这里分叉了你的 codepen 测试用例:https ://codepen.io/bobacus/pen/MLjZMg
我想知道是否需要将侦听器添加到<li>元素中,因此更改了一些代码:
listEl = document.getElementById('my_list');
for (var i = 0; i < listEl.children.length; i ++) {
itemEl = listEl.children[i];
itemEl.addEventListener('dragstart', function(event) {
dragging = getLI(event.target);
if (dragging) {
event.dataTransfer.setData('text/plain', null);
event.dataTransfer.setDragImage(dragging, 0, 0);
}
});
}
Run Code Online (Sandbox Code Playgroud)
但这没有用。
我尝试了一些不同的方法,但最终让它在 Safari 中工作的是添加此处描述的polyfill: https: //www.codeproject.com/Articles/1091766/Add-support-for-standard-HTML-Drag-and - 跌落操作
我将其添加到 HTML 片段的顶部:
<script src="http://bernardo-castilho.github.io/DragDropTouch/DragDropTouch.js"></script>
Run Code Online (Sandbox Code Playgroud)
我希望这是有帮助的。
不幸的是我没有带有iOS12的设备(我的设备不支持它)并且我无法测试它。我不知道为什么 iOS/Apple 支持写道他们在 iOS 11.2 中支持此事件,而在您的新设备上则不受支持。
替代解决方法
通过此解决方法,您将获得适用于所有现代设备和浏览器的解决方案。这比等待 iOS/Apple 的支持要好。
dragstart、dragover、dragleave、drop事件不适用于所有触摸设备。
您必须为触摸事件使用适当的事件名称,例如:
touchstarttouchendtouchcanceltouchmove阅读有关此事件的文档。
为了为基于触摸的用户界面提供高质量支持,触摸事件提供了解释触摸屏或触控板上手指(或手写笔)活动的能力。
触摸事件接口是相对较低级别的 API,可用于支持特定于应用程序的多点触摸交互,例如两指手势。当手指(或触笔)首次触摸接触表面时,多点触摸交互开始。其他手指随后可以触摸该表面并且可选地在触摸表面上移动。当手指离开表面时,交互结束。在此交互过程中,应用程序在开始、移动和结束阶段接收触摸事件。
触摸事件与鼠标事件类似,不同之处在于它们支持同时触摸并且位于触摸表面的不同位置。TouchEvent 接口封装了当前活动的所有触摸点。触摸界面代表单个触摸点,包括触摸点相对于浏览器视口的位置等信息。
不幸的是,事件touchenter和touchleave已从规范中删除,因此如果您需要它,则必须使用document.elementFromPoint()如下所示编写解决方法:
document.addEventListener('touchmove', function(e)
{
var touch = e.touches[0],
elementFromPoint = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset);
if(elem == elementFromPoint) //elem is your element which was entered
{
//your code for touchenter event
}
else //the code for touchleave event
});
Run Code Online (Sandbox Code Playgroud)
也许对于其他一些移动设备及其浏览器,您将需要使用 polyfills ( 1 , 2 ),它可以在移动(触摸)设备上启用 HTML5 拖放支持。
| 归档时间: |
|
| 查看次数: |
9147 次 |
| 最近记录: |