使用 Drag and Drop 給Web應用提高交互體驗

什麼是 Drag and Drop (拖放)?

簡單來講,HTML5 提供了 Drag and Drop API,容許用戶用鼠標選中一個可拖動元素,移動鼠標拖放到一個可放置到元素的過程。css

我相信每一個人都或多或少接觸過拖放,好比瀏覽器多標籤頁之間的可拖放排序、手機中的App能夠隨便拖放排序等等,Drag and Drop 已經給咱們提供了更便捷、更靈活的網絡應用體驗。html

HTML5 Drag and Drop

DnD 規範定義了基於事件的拖放機制和附加標記,以標記網頁上幾乎全部 draggable 的元素類型,一個典型的 drag 操做是這樣開始的:用戶用鼠標選中一個可拖動的(draggable)元素,移動鼠標到一個可放置的(droppable)元素,而後釋放鼠標。 在操做期間,會觸發一些事件類型,有一些事件類型可能會被屢次觸發(好比drag 和 dragover 事件類型)。vue

總結起來很簡單:html5

Drag Source(What to drag) => Drop Target(Where to drop)react

dnd-example

拖拽事件

全部的拖拽事件都對應一個 global event handler,Dnd API 一個有8個事件,能夠分爲綁定在 Drag Source 上3個、綁定在 Drag Target 上5個git

Drag Source

Event Description
dragstart 當用戶開始拖動一個元素或選中的文本時觸發。
drag 當拖動元素或選中的文本時觸發。
dragend 當拖拽操做結束時觸發 (好比鬆開鼠標按鍵或敲「Esc」鍵)。

Drop Target

Event Description
dragenter 當拖動元素或選中的文本到一個可釋放目標時觸發。
dragover 當元素或選中的文本被拖到一個可釋放目標上時觸發(每100毫秒觸發一次)。
dragexit 當元素變得再也不是拖動操做的選中目標時觸發。
dragleave 當拖動元素或選中的文本離開一個可釋放目標時觸發。
drop 當元素或選中的文本在可釋放目標上被釋放時觸發。

dnd-event-flow

注意點

  • 在鼠標操做拖放期間,有一些事件可能觸發屢次,(好比:dragdragover)。使用時注意防抖節流
  • dragover 事件中使用 event.preventDefault() 阻止默認事件行爲時,才能正確觸發 drop 事件
  • 在 Firefox 瀏覽器中觸發 drop 時要使用 event.preventDefault() 阻止默認事件行爲,以防止打開一個新的標籤

數據接口

HTML拖拽的數據接口有三個 DataTransferDataTransferItemDataTransferItemListgithub

在進行拖放操做時,DataTransfer 對象用來保存,經過拖放動做,拖動到瀏覽器的數據。它能夠保存一項或多項數據、一種或者多種數據類型。web

DataTransfer 經常使用屬性

屬性 類型 描述
dropEffect String 獲取 / 設置實際的放置效果,它應該始終設置成 effectAllowed 的可能值之一,copymovelinknone
effectAllowed String 用來指定拖動時被容許的效果。
Files FileList 保存一個被存儲數據的類型列表做爲第一項,順序與被添加數據的順序一致。若是沒有添加數據將返回一個空列表。
types DOMStringList 包含一個在數據傳輸上全部可用的本地文件列表。若是拖動操做不涉及拖動文件,此屬性是一個空列表。

DataTransfer 經常使用方法

  • void clearData([in String type])
  • String getData(in String type)
  • void setData(in String type, in String data)
  • void setDragImage(in nsIDOMElement image, in long x, in long y)

dnd-data

注意點

  • 經過定義 MIME (Multipurpose Internet Mail Exchange)來指定數據傳輸類型,例如:text/plain

功能檢測

想象一下咱們想開發一個使用HTML5 DnD API來實現的豐富可交互式的應用。結果由於瀏覽器不支持,是否是很糟糕。對咱們是否須要使用降級方案仍是有很重要的參考意義的。瀏覽器

下面有兩種經常使用的方法來幫助咱們來檢測。網絡

caniuse

caniuse-dnd

Modernizr

Modernizr 是一個出色的可用於檢測用戶瀏覽器是否支持 HTML5CSS3 功能的庫。

if (Modernizr.draganddrop) {
  // Browser supports HTML5 DnD.
} else {
  // Fallback to a library solution.
}
複製代碼

實現拖拽

HTML Attribute

實現拖拽元素只須要在dom標籤上加入 draggable="true"

<div id="drag-source" draggable="true"></div>
複製代碼

CSS User Interface

user-select

可拖拽元素,建議使用 user-select,避免用戶在拖拽時選取到內部元素。

[draggable="true"] {
  /* To prevent user selecting inside the drag source */
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
}
複製代碼

cursor

可拖拽元素,建議使用 cursor,設定可拖拽元素的鼠標遊標,提高交互。

[draggable="true"] {
  cursor: move;
}
複製代碼

在 Vue 中使用拖拽

Vue 中使用 dnd 能夠直接綁定 event 到組件上。

下面栗子包含的內容:

  • 使用Vue實現拖放
  • 拖放事件以及事件觸發的時機
  • 拖放事件的一些效果處理
  • 拖拽系統文件到瀏覽器

Edit DnD Demo

DnD 能作什麼?

  • 提高網頁上操做交互體驗
  • 提供列表排序功能
  • 本機與瀏覽器交互
  • HTML5遊戲
  • ...更多

推薦一些不錯的DnD庫

  • interact.js - JavaScript drag and drop, resizing and multi-touch gestures with inertia and snapping for modern browsers (and also IE9+)
  • Sortable - Sortable — is a JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices.
  • draggable - The JavaScript Drag & Drop library your grandparents warned you about.
  • Vue.Draggable - Vue component allowing drag-and-drop sorting in sync with View-Model. Based on Sortable.js
  • vue-grid-layout - A draggable and resizable grid layout, for Vue.js.
  • vue-draggable-resizable - Vue2 Component for draggable and resizable elements.
  • react-dnd - Drag and Drop for React
  • react-beautiful-dnd - Beautiful and accessible drag and drop for lists with React
  • react-grid-layout - A draggable and resizable grid layout with responsive breakpoints, for React.

參考

Mozilla HTML_Drag_and_Drop_API

Native HTML5 Drag and Drop

caniuse

Working with HTML5 Drag-and-Drop

原文:使用 Drag and Drop 給Web應用提高交互體驗

相關文章
相關標籤/搜索