在移动设备上添加对标准 HTML5 拖放操作的支持






4.97/5 (27投票s)
Polyfill,可在移动(触摸)设备上启用 HTML5 拖放支持。
问题
HTML5 规范包含对拖放操作的支持。
所有现代桌面浏览器都支持这一点,但在 Android 和 IOS 上运行的移动浏览器不支持。这是一个问题,因为使用 HTML5 开发应用程序的主要原因之一是能够在所有设备上运行。
我怀疑移动浏览器不支持拖放有两个原因:
- 它们的屏幕通常太小,无法进行有用的拖放操作。
- 它们使用触摸屏进行滚动和缩放等其他任务,这可能会干扰拖放。
但是,许多移动设备都有足够大的屏幕。这包括几乎所有的平板电脑和许多手机。而且,为了支持拖放,无法通过拖动某些元素(具有 draggable 属性的元素)来进行滚动或缩放,这似乎是一个合理的权衡。
因此,要在当今的移动设备上使用拖放,您有两个选择:
- 忘记 HTML5 拖放 API,而是使用自定义拖放库(您自己的,或几个现有选项之一);或
- 使用 polyfill,将触摸事件转换为 HTML5 拖放事件。
我们更倾向于第二种方法,因为标准很重要。遵循 HTML 拖放标准而不是使用自定义库意味着您现有的拖放代码将与基于标准的框架和组件一起使用,而无需进行重大更改。
例如,几个 Wijmo 控件大量使用 HTML5 拖放。
- FlexGrid 使用它来重新排列和调整行和列的大小。
- GroupPanel 使用它来重新排列和排序组。
- PivotPanel 使用它来构建 OLAP 视图并提供上下文菜单。
不幸的是,直到最近,所有这些功能在移动设备上运行时都受到限制或不存在。您可以使用鼠标拖放网格列、组和透视字段,但不能使用触摸。
解决方案
当我们的客户告诉我们他们希望在移动设备上支持拖放操作时,我们决定采用 polyfill 方法,并实现了一个 DragDropTouch 类,该类会透明地将触摸事件转换为 HTML5 拖放事件。这使我们能够一次性改进所有控件的触摸支持,而无需更改任何控件。
DragDropTouch polyfill 的工作原理如下:
- 它附加到触摸事件的监听器。
- 在 touchstart 时,它会检查目标元素是否具有 draggable 属性,或者是否包含在具有该属性的元素中。如果是这种情况,它会保存对此“拖动源”元素的引用,并阻止事件的默认处理。
- 在 touchmove 时,它会检查触摸是否已从原点移动到某个阈值距离。如果是这种情况,它会触发 dragstart 事件,并继续监视移动以触发 dragenter 和 dragleave。
- 在 touchend 时,它会触发 dragend 和 drop 事件。
这足以处理拖放,但不足以完全支持触摸。问题是,一旦在可拖动元素上检测到触摸,就必须阻止事件的默认处理,以防止滚动。但并非所有触摸都是为了启动拖放操作。用户可能只想单击/点按元素,或者双击它,或者显示上下文菜单。
换句话说,仅仅为触摸操作提供拖放支持是不够的;当触摸不是拖放操作时,polyfill 不能干扰。
由于这个要求,polyfill 必须执行一些额外的任务:
- 当用户触摸可拖动元素但未开始拖动时,触发 mousemove、mousedown、mouseup 和 click 事件。
- 当单击后紧接着发生新的 touchstart 时,触发 dblclick 事件,并且
- 当触摸持续一段时间但用户没有开始拖动元素时,触发 contextmenu 事件。
就这样。
使用 polyfill 非常简单。您所要做的就是在您的页面中添加此脚本标记:
<script src="scripts/DragDropTouch.js"></script>
该脚本将自动创建一个 DragDropTouch 类的实例,并开始转换事件,从而使 Android 和 IOS 设备上的拖放操作能够像在桌面浏览器上一样工作。
我们创建了一个示例,该示例使用经典的 HTML5 拖放示例以及一些 Wijmo 控件来演示 polyfill 的效果。您可以在此处查看该示例:
http://bernardo-castilho.github.io/DragDropTouch/demo/
下图显示了该示例在 iPad 上运行,用户正在将元素 A 拖动到新位置。
结论
实现 polyfill 来将触摸操作转换为拖放事件,是在不中断的情况下增强基于标准组件的可用性,使其支持移动设备上的拖放操作的有效方法。
上述 polyfill 将鼠标支持扩展到支持拖放操作的几个 Wijmo 控件,但它是通用的,因此它也可以与其他基于标准的组件和应用程序一起使用。
您所要做的就是在您的应用程序中添加一个脚本标记,在 iPad 上打开它,然后开始拖动!
本文包含许多关于不同类型指针事件的有趣信息,包括鼠标、触摸以及提议的“指针事件”统一标准。
http://www.html5rocks.com/en/mobile/touchandmouse/
本文专门介绍 HTML5 拖放。