1. 程式人生 > >HTML5元素拖拽drag與拖放drop相關API

HTML5元素拖拽drag與拖放drop相關API

其實HTML5就是新增一些有用的API
讓我們更輕鬆的開發
從而把更多精力都放在業務邏輯上來
這些API的使用也非常簡單
不過我的記性不太好
所以還是以部落格的形式記錄下來(手動滑稽)
今天就來寫一下這個拖拽API

預設拖拽

說起拖放,其實最早實現拖放功能的還是IE(IE4)
H5就是在IE例項的基礎上指定的拖拽規範
在瀏覽器中,是有預設拖拽的
比如說圖片的拖拽

選中文字的拖拽

連結的拖拽

元素拖拽

瀏覽器預設允許我們拖拽影象、文字以及連結
讓其它元素被拖動也是可以實現的
只需要在元素標籤上新增一個屬性

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

當拖拽這個元素的時候,瀏覽器就會以半透明覆本的方式顯示

拖拽事件

拖拽事件應該分為兩類
一類是被拖拽元素觸發的事件
另一類是拖放目標元素觸發的事件

<div id="source" draggable="true"></div>
<div id="target"></div>  <!-- 樣式略 --> 
var source = document.getElementById('source');
var target = document.getElementById('target'
);

拖拽元素

拖拽元素的時候,被拖拽元素會觸發以下事件

  • dragstart
  • drag
  • dragend

當滑鼠點中元素並且開始移動時,就會觸發dragstart事件(類比mousedown)
拖拽過程中會持續不斷地觸發drag事件(類比mousemove)
鬆開滑鼠取消拖拽時就會觸發dragend事件(類比mouseup)

source.ondragstart = function(){
  console.log('開始拖拽');
}
source.ondrag = function(){
  console.log('拖拽中');
}
source.ondragend = function
(){
console.log('拖拽結束'); }

目標元素

當拖拽的元素拖到一個目標元素上時,目標元素會觸發以下事件

  • dragenter
  • dragover
  • dragleave
  • drop

拖拽元素到目標上,就會觸發dragenter事件(類比mouseover)
當拖動元素在目標元素中,就會持續觸發dragover事件
離開目標元素,觸發dragleave事件(類比mouseout)
若拖放元素到了目標元素中(在目標元素中鬆開滑鼠),就會觸發drop事件而不會觸發dragleave事件

target.ondragenter = function(){
  console.log('拖動進入目標元素');
}
target.ondragover = function(){
  console.log('目標元素中拖拽');
}
target.ondragleave = function(){
  console.log('拖動離開目標元素');
}
target.ondrop = function(){
  console.log('拖放');
}

這時我們會發現元素拖放到目標元素中時
並沒有觸發drop事件

我們看到了一個特殊的游標(圓環+反斜線)
意思就是無效的拖放
所以導致沒有觸發drop事件
也就是說元素預設是不能夠拖放
只要我們在目標元素的dragover事件中取消預設事件就可以解決問題

target.ondragover = function(e){
  console.log('目標元素中拖拽');
  e.preventDefault(); //增
}

資料交換

只是簡單的拖放毫無意義
我們需要進行資料交換
而這個用語資料交換的物件就是事件物件的屬性dataTransfer
dataTransfer的兩個核心方法是setData()和getData()
setData()用於設定資料,getData()用語接收資料

event.dataTransfer.setData('text','some text');

var text = event.dataTransfer.getData('text');
//儲存在dataTransfer中的資料只能在drop事件處理函式中處理

如果我們拖拽了選中文字
那麼瀏覽器預設就會呼叫dataTransfer.setData,設定對應文字資料

setData()和getData()就是資料型別的字串
IE定義的資料型別除了“text”文字型別還有“URL”
H5對它進行了擴充套件,可以指定各種MIME型別
但為了向後相容,它同樣支援“text”和“URL”
它們會被分別對映為“text/plain”和“text/uri-list”

如果資料儲存為URL,瀏覽器會做特殊處理,把它當成網頁連結
(所以拖拽連結到另外的瀏覽器視窗就會開啟網頁)

必要的話,我們可以手動儲存需要傳輸的資料

var source = document.getElementById('source');
var target = document.getElementById('target');
source.ondragstart = function(e){
  e.dataTransfer.setData('text','傳遞文字資料');
}
target.ondragover = function(e){
  e.preventDefault();
}
target.ondrop = function(e){
  console.log(e.dataTransfer.getData('text'));
}

拖拽設定

在dataTransfer中還有兩個重要的屬性
dropEffecteffectAllowed

dropEffect

dropEffect屬性值為字串,表示被拖動元素可以執行哪一種放置行為
要使用這個屬性,必須在dragenter事件處理函式中設定

  • none 不能把元素拖放至此(除文字框外全部元素的預設值)
  • move 移動到目標
  • copy 複製到目標
  • link 目標開啟拖動元素(拖動元素必須是連結並有URL)

effectAllowed

effectAllowed屬性值也是字串,表示允許拖動元素哪種dropEffect
要使用這個屬性,必須在dragst事件處理函式中設定

  • uninitialized 沒有設定任何拖放行為
  • none 不能由任何行為
  • copy 僅允許dropEffect值為copy
  • link 僅允許dropEffect值為link
  • move 僅允許dropEffect值為move
  • copyLink 允許dropEffect值為copy和link
  • copyMove 允許dropEffect值為copy和move
  • linkMove 允許dropEffect值為link和move
  • all 允許任意dropEffect