HTML5 的拖拽介紹

本文主要介紹與拖拽操做相關的對象及事件信息,但並不涉及太多的源碼演示。javascript

一個簡單的示例

在html5中要實現拖放操做,相對於之前經過鼠標操做實現,要簡單得多,數據安全性也更有保障。只須要如下幾步便可。html

  1. 給被拖拽元素添加draggable屬性,若是是文件拖放。
  2. 爲目標元素添加一個dropzone屬性,這一步也不是必須的,能夠省略。
  3. 在拖拽元素的dragstart中初始化相關的數據信息,主要是DataTransfer對象。
  4. 在目標元素的dragover事件中,取消其默認操做。
  5. 在目標元素的drop事件中,處理接受到的數據。
  6. 在被拖拽元素的dragend事件中,作善後工做。若沒有則能夠省略。

大體代碼以下:html5

 

<div id="source" draggable="draggable">source</div>
<div id="target">target</div>
<script type="text/javascript">
    var target = document.getElementById('target');
    var source = document.getElementById('source');
    source.ondragstart = function(e) {
        e.dataTransfer.effectAllowed = 'copyMove';
        e.dataTransfer.setData('test', 'testData');
    };
    target.ondragover = function(e) {
        e.dataTransfer.dropEffect = 'move';
        e.preventDefault(); // 不能少 
  };
  target.ondrop = function(e){
    var elem = document.createElement('a');
    elem.innerHTML = e.dataTransfer.getData('test');
    e.target.appendChild(elem);
  };
</script>

 

draggable屬性

draggable是一個枚舉屬性,用於指定一個標籤是否能夠被拖拽。有如下四種取值:java

  1. true:表示此元素可拖拽。
  2. false:表示此元素不可拖拽。
  3. auto:除img和帶href的標籤a標籤表示可拖拽外,其它標籤均表示不可拖拽。
  4. 其它任何值:表示不可拖拽。

dropzone屬性

這個屬性用於接受拖拽元素的目標元素上,表示能接受的數據類型及操做方式。多個值用空格分開,不區分大小寫。其值有如下類型組成:windows

  • copy:表示將容許的元素放到該元素上時,會將拖拽數據複製到目標元素上。
  • link:表示將容許的元素放到該元素上時,將連接數據到目標元素上。
  • move:表示將容許的元素放到該元素上時,會將數據移動到目標元素上。
  • string:開頭的字符串,長度不能小於8個字符:表示能接受DataTransferItem.kind值爲stringdata對象。
  • file:開頭的字符串,長度不能小於6個字符:表示能接受DataTransferItem.kind值爲fileDataTransferItem.type的值匹配file:以後的字符的DataTransferItem的對象。

相關的事件

DragEvent接口定義

DragEventMouseEvent接口繼承,其定義以下,與MouseEvent相比,只是多了個DataTransfer對象。全部針對拖拽的操做也是經過控制此對象來完成的。數組

[Construct(DOMString type, optional DragEventInit eventInitDict)] interface DragEvent: MouseEvent {
    readonly attribute DataTransfer ? dataTransfer;
};
/* 這是用於初始事件的參數定義 */
dictionary DragEventInit: EventInit {
    // 從UIEvent繼承的屬性:   
    Window ? view = null;
    long detail = 0;
    // 從MouseEvent繼承的屬性:   
    long screenX = 0;
    long screenY = 0;
    long clientX = 0;
    long clientY = 0;
    boolean ctrlKey = false;
    boolean shiftKey = false;
    boolean altKey = false;
    boolean metaKey = false;
    unsigned short button = 0;
    unsigned short buttons = 0;
    EventTarget ? relatedTarget = null;
    // DragEvent添加的新屬性:   
    DataTransfer ? dataTransfer;
}

 

事件描述

拖拽相關事件
事件名稱 事件目標 可撤消? 存儲模式1 dropEffect值 默認操做 備註
1.存儲模式是針對於DataTransfer對象的操做,具體數據見後表。
dragstart 被拖拽元素 讀、寫 none 初始化操做 若調用preventDefault()函數取消此事件的默認行爲,則拖拽功能將被取消。
drag 被拖拽元素 保護模式 none   在dragstart以後,釋放鼠標以前,無論鼠標是否移動,此事件不停地被觸發。
dragenter 目標元素 保護模式 effectAllowed限定的值。 更換目標元素。 進入目標元素時,觸發一次。
dragleave 離開前的目標元素 保護模式 none   離開時觸發一次。
dragover 目標元素 保護模式 effectAllowed限定的值 重置dropEffect爲none,並中斷後續事件執行。 在dragenter以後,dragleave以前,不論是否移動,此事件都將不停地觸發。
drop 目標元素 只讀模式 當前設定的值   釋放鼠後,由目標元素觸發。
dragend 被拖拽元素 保護模式 當前設定的值   釋放鼠標後,由被拖拽元素觸發,順序在drop以後。

目標元素是指當前鼠停留的元素,如要將A元素拖放到F元素上,中間通過的全部元素,在鼠標通過期間都是一個目標素,相應的事件都會被觸發,A元素自己就是第一個目標元素。瀏覽器

DataTransfer接口

在HTML5中,爲了實如今拖放過程當中的數據交換,給全部的拖拽事件提供了一個DataTransfer屬性。經過此對象的方法和屬性來完善拖放功能。安全

interface DataTransfer {
    attribute DOMString dropEffect;
    attribute DOMString effectAllowed;
    void setDragImage(Element image, long x, long y);
    readonly attribute DOMString[] types;
    DOMString getData(DOMString format);
    void setData(DOMString format, DOMString data);
    void clearData(optional DOMString format);
    readonly attribute DataTransferItemList items;
    readonly attribute FileList files;
}

 

effectAllowed和dropEffect

這兩個屬性用於描述在拖拽過程當中,鼠標顯示的樣式,受瀏覽器和操做系統的影響,鼠標顯示的圖標並不一致。app

effectAllowed表示這次拖拽容許顯示的鼠標樣式,能夠是如下值:nonecopycopyLinkcopyMovelinklinkMovemovealluninitialized。只能在dragstart事件中更改此值。函數

dropEffect表示這次拖拽過程當中顯示的樣式,能夠是如下幾個值:copymovelinknone。在具體的拖拽過程當中,還受effectAllowed值限定,具體限定內容見下表,當dropEffect的值被設置爲一個不屬於effectAllowed限定的值時,整個事件鏈將被停止,即後續事件都將不會被觸發,但不會發生任何錯誤提示。

effectAllowed與dropEffect對照表
effectAllowed dropEffect
1:根據用戶所使用的平臺不一樣,可能會出現的值,如在windows下,copyMove的effectAllowed值,默認爲copy操做,在按shift鍵時,則會變成move操做。
none none
copy copy
copyLink copy或是link1
copyMove copy或是move1
all copy、link1或是move1
link link
linkMove link或是move1
move move
uninitialized,被拖拽爲一個文本框中選中的內容? move或是copy1,link1
uninitialized,被拖拽對象爲一個普通選中項? copy或是link1,move1
uninitialized,被拖拽對象爲一個帶連接的a元素 link或是copy1,move1
其它狀況 copy或是link1,move1

setDragImage(image, x, y)

這個函數用於設置鼠標移動過程當中隨鼠標一塊兒移動的效果圖,而不是鼠標指針的顯示效果。xy參數用於指定圖像相對於鼠標指針的位置;image參數用於指定圖像元素,如果一個img元素,則顯示圖像元素,不然將給定的元素轉換成一張圖像並顯示。

該函數只能在讀寫模式(也就是dragstart事件)下有用,在其它事件中調用無效。若不調用此函數,則在拖拽時,被拖拽元素被轉換成一個圖處並看成一個效果圖顯示。

items屬性

items的接口定義以下:

interface DataTransferItemList {
    readonly attribute unsigned long length;
    getter DataTransferItem(unsigned long index);
    // items[index]   
    deleter void(unsigned long index);
    // delete items[index]   
    void clear();
    DataTransferItem ? add(DOMString data, DOMString type);
    DataTransferItem ? add(File data);
}
interface DataTransferItem {
    readonly attribute DOMString kind;
    readonly attribute DOMString type;
    void getAsString(FunctionStringCallback ? _callback);
    File ? getAsFile();
} 
[Callback, NoInterfaceObject] 
interface FunctionStringCallback {
    void handleEvent(DOMString data);
}

從上面的定義不難看出:DataTransfer.items就是DataTransferItem的一個數組。DataTransferItemList僅僅是定義一套以數組形式存取DataTransferItem對象的接口。咱們主要看一下DataTransferItem類的定義:

  • kind:表示數據的類型,只能是stringFile。單從字面就很好理解這兩個值表明的是什麼意思。
  • type:實際數據的類型或是格式,通常用mimetype表示,但並非強制mimetype格式。
  • getAsString(callback):當kind屬性爲string時,在只讀或是讀寫模式下,能夠經過回調函數處理此對象關聯的實際數據。
  • getAsFile():當kindfile是,經過此函數能獲取真實的數據,不然返回null,只在只讀或是讀寫模式下有效。

在非讀寫模式下刪除DataTransferItemList中的數據,會返回InvalidStateError錯誤。如果在非讀寫模式下添加數據,則不執行任何操做。DataTransfer.setData則是對這兩個函數的封裝(根據第二個參數決定是刪除仍是添加)。

types屬性

返回根據下列步驟產生的字符串集合(DOMStringList):

  1. 產生一個空的DOMStringList對象L。
  2. 遍歷DataTransfer.items對象。
  3. DataTransfer.items的子項的kind的值爲string,則將該項的type值添加到L對象中。
  4. DataTransfer.items的子項的kind的值爲file,則向L對象添加"Files"字符串。
  5. 返回L對象

getData(format)

getData是從DataTransfer.items中查找數據。返回符合如下條件的數據:

  1. DataTransferItem.kindstring
  2. DataTransferItem.type的值等於format參數

若是沒有找到匹配的或是處於保護模式下,則返回一個空字符串。

參數format在傳遞到函數內部以前,都會被轉換成小寫字符,且若是參數值爲text或是url,則會被轉換成text/plaintext/uri-list

setData(format, data)

setData用於向DataTransfer.items中添加或刪除一條數據:

當沒有指定第二個參數data時,則是從DataTransfer.items中刪除符合如下條件的數據:

  1. kind等於string
  2. type等於參數format

當指定第二個參數data時,則是向DataTransfer.items中添加數據,新添加的數據格式以下:

  1. kind的值爲string
  2. type的值爲format
  3. data參數做爲DataTransferItem的實際值。

參數format在傳遞到函數內部以前,都會被轉換成小寫字符,且若是參數值爲text或是url,則會被轉換成text/plaintext/uri-list

若是不處於讀寫模式下,則不作任何操做。

clearData()

清除全部kind值爲string的項。只在讀寫模式下起做用。

存儲模式

存儲模式決定了DataTransfer各項內容是否可用。下表列出相關的信息,其中Y表示可用,N表示不可用。

存儲模式與 DataTransfer各項的關係
  讀寫 只讀 保護
dropEffect 只在dragenterdragover事件中可更改,其它事件中只可讀取。
effectAllowed 只在dragstart事件中起做用
items 對items的操做詳細狀況參考後面的setData函數
types 僅在dragenterdragoverdrop三個事件中可獲取此值
setData Y N N
getData Y Y N
clearData Y N N
DataTransferItem.getAsString Y Y N
DataTransferItem.getAsFile Y Y N

來自:http://blog.830725.com/post/html5-drag-and-drop-intro.html

相關文章
相關標籤/搜索