文件拖放

HTML 拖放接口使 Web 应用程序能够在网页上拖放文件。本文档描述了应用程序如何接受从底层平台的文件管理器中拖放的一个或多个文件并将其放置在网页上。

拖放的主要步骤是定义一个放置区(即文件放置的目标元素)以及为 dropdragover 事件定义事件处理程序。这些步骤将在下面进行描述,包括示例代码片段。完整的源代码可在 MDN 的拖放仓库 中找到(欢迎拉取请求和/或问题)。

请注意,HTML 拖放 定义了两个不同的 API 来支持拖放文件。一个 API 是 DataTransfer 接口,另一个 API 是 DataTransferItemDataTransferItemList 接口。本示例说明了这两个 API 的使用(并且不使用任何 Gecko 特定的接口)。

定义放置区

需要为 drop 事件的目标元素添加 ondrop 事件处理程序。以下代码片段显示了如何使用 <div> 元素来完成此操作。

html
<div id="drop_zone" ondrop="dropHandler(event);">
  <p>Drag one or more files to this <i>drop zone</i>.</p>
</div>

通常,应用程序会在放置目标元素上包含一个 dragover 事件处理程序,该处理程序会关闭浏览器的默认拖动行为。要添加此处理程序,需要包含一个 ondragover 事件处理程序。

html
<div
  id="drop_zone"
  ondrop="dropHandler(event);"
  ondragover="dragOverHandler(event);">
  <p>Drag one or more files to this <i>drop zone</i>.</p>
</div>

最后,应用程序可能希望对放置目标元素进行样式设置,以直观地指示该元素是一个放置区。在本例中,放置目标元素使用以下样式。

css
#drop_zone {
  border: 5px solid blue;
  width: 200px;
  height: 100px;
}

注意:当从操作系统将文件拖动到浏览器时,不会触发 dragstartdragend 事件。要检测何时将操作系统文件拖动到浏览器,请使用 dragenterdragleave。这意味着在从操作系统拖动文件时,无法使用 setDragImage() 来应用自定义拖动图像/光标叠加层——因为拖动数据存储只能在 dragstart 事件中修改。这也适用于 setData()

处理放置操作

当用户放置文件时,会触发 drop 事件。在以下放置处理程序中,如果浏览器支持 DataTransferItemList 接口,则使用 getAsFile() 方法访问每个文件;否则,使用 DataTransfer 接口的 files 属性访问每个文件。

此示例显示了如何将每个拖动文件的名称写入控制台。在实际应用中,应用程序可能希望使用 文件 API 处理文件。

请注意,在本例中,任何非文件的拖动项目都会被忽略。

js
function dropHandler(ev) {
  console.log("File(s) dropped");

  // Prevent default behavior (Prevent file from being opened)
  ev.preventDefault();

  if (ev.dataTransfer.items) {
    // Use DataTransferItemList interface to access the file(s)
    [...ev.dataTransfer.items].forEach((item, i) => {
      // If dropped items aren't files, reject them
      if (item.kind === "file") {
        const file = item.getAsFile();
        console.log(`… file[${i}].name = ${file.name}`);
      }
    });
  } else {
    // Use DataTransfer interface to access the file(s)
    [...ev.dataTransfer.files].forEach((file, i) => {
      console.log(`… file[${i}].name = ${file.name}`);
    });
  }
}

阻止浏览器的默认拖动行为

以下 dragover 事件处理程序调用 preventDefault() 来关闭浏览器的默认拖放处理程序。

js
function dragOverHandler(ev) {
  console.log("File(s) in drop zone");

  // Prevent default behavior (Prevent file from being opened)
  ev.preventDefault();
}

另请参阅