黄子涵

第15章 与桌面应用的协作

15.1 Drag Drop API

15.1.1 Drag Drop API 的定义

Drag Drop API 是一种能够在浏览器中实现 DOM 元素的拖动与释放操作的 API。拖动与释放功能非常重要,它可以使 Web 应用程序具有接近原生桌面程序的易用性。众所周知,拖动与释放这一功能,其实在很久以前就已经在浏览器中得以实现。那么,和过去的拖动操作相比,这一 API 究竟有哪些不同之处呢?

实现方式上的区别

过去实现拖动与释放操作的基本方式基于下面的三个流程。其想法本身非常简单,不过,由于从鼠标移动开始,一直到更新 DOM 元素的显示为止,都需要自己管理,因此在实际使用时非常麻烦。

  • 通过 mousedown 事件来捕捉 DOM 元素
  • 通过 mousemove 事件来移动 DOM 元素
  • 通过 mouseup 事件来释放 DOM 元素

而借助于 Drag Drop API,通过 dragstart 及 drop 等新添加的高度抽象的事件,就能够实现更为直观的拖动与释放操作。同时,由于拖动过程中基本的显示更新处理也都交由浏览器来进行,从而使开发者能够将精力集中于程序的开发,以实现运用了这一拖动操作的应用程序。

功能上的区别

当前,人们已经开发了大量支持拖动与释放操作的库。只要利用这些库,就能够很轻松地将跨浏览器支持的拖动与释放功能嵌入应用程序之内。在这种情况下,仍要坚持使用 Drag Drop API 的意义是什么呢?

答案就在 DataTransfer 中。DataTransfer 是对拖动操作中数据的接受与传递提供支持的 API。值得一提的是,通过 DataTransfer 传送数据有一些重要的优点。例如,数据的发送方(拖动起始处)与数据的接收方(释放处)并未限定于同一窗口内。

举例来说,可以由此实现将浏览器中的 DOM 元素拖向文本编辑器,或者将桌面上的文件拖向浏览器等操作。Drag Drop API消除了 Web 应用程序与原生应用程序之间的界限,是一种非常重要而充满魅力的功能。

15.1.2 接口

拖动事件

由 Drag Drop API 进行拖动与释放时,数据的发送方(拖动的元素)与接收方(释放的区域)这两者之间是一种松耦合的实现方式。通过对拖动的元素与释放的区域分别实现必要的事件处理程序,就能够完成拖动操作。

表15.1 能够设定拖动元素的事件处理程序

image

表15.2 能够设定释放区域的事件处理程序

image

这些拖动事件继承了鼠标事件的接口,因此也可以通过 screenX 及 clientX 等鼠标事件的属性来确认拖动过程中的位置。曾经使用鼠标事件来实现拖动与释放功能的人,应该已经对相应事件的使用方法有一个大概的理解了吧。

由于拖动事件将会根据拖动操作的状态和合适的时机被触发,因此不必由自己来管理与拖动释放相关的复杂的旗标。例如,drag 事件及 dragover 事件被限定于仅会在拖动操作中被触发。它们与 mouseover 事件不同,即使鼠标没有处于移动状态,也会被定期触发。

各个事件处理程序将会接收以 DataTransfer 形式保存的数据,并对 UI 显示的更新功能进行实现。在使用 Drag Drop API 进行拖动操作时,被拖动元素的捉取图像默认将会随着鼠标的移动而显示相应的内容,而拖动过程中的页面滚动等处理也都将由浏览器来解决。因此,如果没有特别的需求,在最初不考虑拖动中的 UI 显示处理也不会有什么问题。

DataTransfer

DataTransfer 是 Drag Drop API 中的核心部分。在所有的拖动事件的事件对象中,都含有 dataTransfer 属性。DataTransfer 最为重要的功能是接收数据,但同时也具有一些其他功能。

  • 数据的接收
  • 数据处理方式的指定
  • 拖动图像的设定
表15.3 DataTransfer的接口一览

image
image

15.1.3 基本的拖动与释放

只要使用 dataTransfer 与最低限度所必需的事件处理程序,就能够实现简单的能够接收数据的范例程序。请通过这一范例来掌握基本的处理流程。

拖动元素的设定

为了使元素能够被拖动,首先要做一些事前的准备处理。要让特定的元素支持被拖动,需要将元素的 draggable 属性设置为 true。

拖动方的设定

拖动方(数据的发送方)需要在开始拖动时将数据设置于 dataTransfer 中。可以调用 setData 方法来将所拖动的数据设置给 dataTransfer。setData 是一种只能够在 dragstart 事件处理程序中执行的方法。代码清单 15.1 是一个例子。

setData 的第 1 个参数用于指定数据的格式(MIME Type)。我们可以对 1 次拖动操作指定多个格式的数据。虽然从标准上来说任何格式都是能够被指定的,但实际的实现情况会根据浏览器的不同而有所不同。在代码清单 15.1 的例子中所指定的 MIME Type,至少在最新版的主流浏览器中都是被支持的。

释放方的设定

接下来,我们来对释放方(数据的接收方)进行实现。可以调用 getData 方法来从 dataTransfer 中获取被拖动的数据。getData是一种只能够在 drop 事件处理程序中执行的方法。

在代码清单 15.2 的范例中,释放区域仅会在被拖动的 dataTransfer 所包含的是文本数据的情况下才允许释放操作,并将通过 alert 语句显示被拖动的文本数据。

15.1.2 自定义显示

如果使用 Drag Drop API,则可以在实现拖动与释放操作时完全不考虑拖动中的 UI 显示问题。不过话虽如此,在拖动与释放操作中,UI的显示也是很重要的部分。本节接下来将介绍根据需要来显示自定义内容的方法。

拖动图像的更改

在拖动过程中显示的图像(拖动图像)默认将使用拖动元素的捉取图像。可以通过 setDragImage 或 addelement 来更改拖动图像。

setDragImage 与 addElement 是仅能在 dragstart 事件中调用的方法。这两个方法都可以以任意 DOM 元素为参数,将所指定的 DOM 元素的捉取图像作为拖动图像来使用。不过,如果指定的 DOM 元素是 img 元素,则不会使用其捉取图像,而会使用 img元素的 src 属性所指定的图像。

setDragImage 与 addElement 的区别在于拖动图像的显示位置不同。setDragImage 以拖动图像的左上角为拖动位置来显示该图像,并且可以通过第 2 及第 3 个参数来指定xy 坐标,以调整显示位置。而 addElement 则将参数所指定的 DOM 元素的当前位置直接作为拖动图像的初始显示位置。

对于诸如日历那样的弹窗式小工具,可以通过 addElement 来移动其显示位置。代码清单 15.3 是一个使用了 addElement 的例子。对于该例这样的情况,如果不通过 addElement 将整个容器指定为拖动图像,则
会默认以 handler 作为拖动图像,从而导致显示错乱。

15.2 File API

15.2.1 File API 的定义

File API 是一种用于获取在本地保存的文件的信息与内容的 API。在 File API 出现之前,我们虽然可以选择本地文件并发送至服务器,但却无法直接通过 JavaScript 读取文件的信息及内容以进行处理。

File API: Writer 与 File API: Directories and System 这两个分别用于文件的写入与文件夹结构管理的 API。目前 W3C 正在对它们的标准进行讨论。

由于具备了这些接口,此前那些只能由原生应用程序实现的用于编辑本地文件与管理的程序也终于能够通过浏览器来实现了。

15.2.2 File 对象

文件的选择

通过引用 File 对象就能够获取文件的信息。为了获取在桌面程序中保存的文件的 File 对象,必须让用户显式地选择文件。可以以两种方法来让用户选择文件。

  • 通过拖动与释放功能进行选择
  • 通过文件选择对话框进行选择

通过拖动与释放操作选择的方法,已经在 15.1 节进行了介绍,在此将仅介绍通过文件选择对话框进行选择的方法。在将 input 元素的 type 属性指定为 "file" 之后,就能够使用操作系统提供的标准的文件选择对话框。

如果要改变对话框的行为,则可以指定 input 元素的 accept 属性与 multiple 属性。通过引用 input 元素的 files 属性就能够获取在对话框中选择的文件的 File 对象。如果希望在文件被选中时就开始处理,则可以侦听 input 元素的 change 事件(表 15.4)。

posted @ 2022-05-16 09:58  黄子涵  阅读(20)  评论(0编辑  收藏  举报