如何使用拖放API

探索如何使用拖放API為您的用戶創建交互式體驗

使用拖放API,您可以定義頁面中的哪些元素是可拖動的,並在用戶拖動元素時進行攔截。

在現代瀏覽器中,它得到了很好的支持:

Browser support

在開始研究API之前,我們必須知道如何定義頁面中的哪些元素可拖動的。我們可以通過添加draggable頁面HTML中的屬性,其值為true

<div draggable="true">
  ...
</div>

這足以使該元素可拖動。

提示:除非您進行設置,否則默認情況下圖像,文本選擇和鏈接是可拖動的draggable對他們虛假

我們還可以從瀏覽器內部的用戶計算機中拖動文件。在這種情況下,我們正在轉移檔案

我們需要澄清的另一點是我們可以將元素拖到哪裡。我們不僅可以拖動任何元素,也不能僅僅拖放到任何元素中。元素必須有效放下目標

要使一個元素成為放置目標,您需要監聽它dragover事件,您要么從中返回false,要么調用preventDefault()關於通過的事件:

const element = document.querySelector('#my-drop-target)
element.addEventListener('dragover', event => {
  event.preventDefault()
})

一旦這樣做,便有了一個可拖動元素和一個放置目標,就可以開始了。我們可以在draggable元素上進行交互的事件是:

  • dragstart
  • drag
  • dragend

在放置目標上:

  • dragenter
  • dragover
  • dragleave
  • drop

拖放操作和触發事件概述

當用戶開始拖動可拖動元素,用鼠標單擊並移動鼠標,或者點按並按住水龍頭,然後移動選區,dragstart事件被觸發:

element.addEventListener('dragstart', event => {
  //...
})

event作為參數傳遞給事件處理函數的對像是DragEvent目的。

它從更一般的角度延伸事件對象,與其他所有事件共享:鼠標,鍵盤,滾動等。

此時,該元素正在被拖動,並且drag事件被觸發。多次拖動該項目,因此我們必須像scroll或者mouseover事件。

我們一進入放下目標

  1. dragenter在放置目標上觸發了事件
  2. dragover在放置目標上觸發了事件

如果拖動的元素先進入放置目標,然後再從其移開,則dragleave事件在放置目標上觸發。

如果用戶釋放鼠標,dragend在要拖動的元素上觸發事件,並且drop事件在放置目標上觸發。

拖動數據:DataTransfer

與拖放相關的每個事件都是DragEvent就像我提到的那樣,它帶有一個名為dataTransfer其中包含要拖動的數據,並提供5個屬性:

  • dropEffect
  • effectAllowed
  • files
  • items(只讀)
  • types(只讀)

當拖動事件開始時,您可以執行一些操作。

設置/獲得效果

您可以通過設置effectAllowed物業dragstart事件。您有一些選項可以設置放置目標應如何處理放置的元素:

  • none它不應該被丟棄
  • move它可以移動
  • copy可以復制
  • link可以鏈接
  • copyMove可以復製或移動
  • copyLink可以復製或鏈接
  • linkMove可以移動或鏈接
  • all可以復制,移動或鏈接

(都是字符串)。

默認是all

dropEffect屬性用於獲取拖放操作的類型,這是用戶這次通過使用修飾鍵設置的類型。例如,在Mac上,按Alt鍵將放置目標設置為複制項目而不是移動項目。

此屬性不是只讀的。我們可以在dragenter或者dragover事件,這些字符串值之一:

  • none它不應該被丟棄
  • move它可以移動
  • copy可以復制
  • link可以鏈接

例子:

element.addEventListener('dragenter', event => {
  event.dataTrasfer.dropEffect = 'move'
})

正在傳輸的數據

您可以訪問從dataTransfer.items屬性,它是一個類似於數組的對象,您可以使用循環對其進行迭代並訪問每個對象DataTransferItem目的。

DataTransferItem具有2個只讀屬性:

  • kind:要拖動的項目的類型。返回包含以下內容的字符串file或者string
  • type項目的MIME類型

它有2種方法:

  • getAsFile()返回一個File表示要拖動的數據的對象
  • getAsString()執行回調函數,粘貼一個字符串對象,該對象表示要拖動的數據

它們的名稱相似,但工作方式卻大不相同。第一個返回一個File目的:

element.addEventListener('dragenter', event => {
  for (item of event.dataTrasfer.items) {
    const theFile = item.getAsFile()
  }
})

了解有關文件對象的更多信息,請訪問https://flaviocopes.com/file/

第二個將項目作為字符串傳遞給回調函數:

element.addEventListener('dragenter', event => {
  for (item of event.dataTrasfer.items) {
    item.getAsString(theString => {
      console.log(theString)
    })
  }
})

被拖動的項目文件的類型存儲在types的屬性dataTransfer目的。它是一個包含字符串的數組string默認情況下。如果我們要拖動文件,則對應的類型是一串值Files

如果有文件正在傳輸,除了列出dataTransfer.items,它們存儲在files的財產dataTransfer

該屬性指向FileList列出要拖動的文件的對象。

在Codepen上查看此演示:

看筆拖放!由Flavio Copes(@flaviocopes) 在密碼筆

Tech Wiki Online!