DragEvent是一個表示drag和drop交互的DOM event介面。用戶通過將指針設備(如:滑鼠)放在目標的錶面開始拖動,然後拖動指針到一個新的位置(如其他DOM元素)。應用程式自動的解析拖放交互。DragEvent介面從mouseEvent和Event那兒繼承屬性。 Event types ...
DragEvent是一個表示drag和drop交互的DOM event介面。用戶通過將指針設備(如:滑鼠)放在目標的錶面開始拖動,然後拖動指針到一個新的位置(如其他DOM元素)。應用程式自動的解析拖放交互。DragEvent介面從mouseEvent和Event那兒繼承屬性。
Event types
DragEvent並不是一個單一的事件,它包含了多個事件,這些事件分別是:drag,dragstart,dragenter,dragend,dragover,dragexit,dragleave,drop。
drag:這個事件在元素拖拽的過程中反覆觸發,每一百毫秒觸發一次。這事件的目標元素是被拖的那個元素,該事件可冒泡,可取消預設行為。
dragstart:這個事件在用戶開始拖動時觸發。這個事件的目標元素是被拖的那個元素,在這些事件中,dragstart事件最先觸發。該事件可冒泡,可取消預設行為。
dragenter:這個事件在被拖的元素進入一個合法的可drop目標時觸發。這個事件的目標元素是這個可drop目標。該事件可冒泡,可取消預設行為。
dragover:當被拖的元素在可drop目標範圍內移動時反覆觸發這個事件,一百毫秒觸發一次。這個事件的目標元素是這個可drop目標。該事件可冒泡,可取消預設行為。
dragend:當拖拽結束時觸發這個事件,這個事件的目標元素是被拖的元素。在這些事件中dragend最後觸發。該事件可冒泡,不能取消預設行為。
dragleave:這個事件在被拖得元素離開合法的可drop目標時觸發。這個事件的目標元素是這個可drop目標。該事件可冒泡,不能取消預設行為。
dragexit:當一個可drop元素不再是拖拽操作最近的drop目標時觸發這個事件。這個事件的目標元素是這個可drop元素。該事件可冒泡,不嫩取消預設行為。
drop:當在可drop目標上鬆開拖動元素的指針設備時觸發這個事件,該事件的目標元素是這個可drop目標。drop事件在dragend事件觸發之前觸發。這個事件可冒泡,可取消預設行為。
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>test target</title> <style type="text/css"> #drag{ width:200px; height:200px; background-color: aqua; } .drop{ width: 300px; height: 300px; background-color: antiquewhite; } </style> </head> <body> <div id="drag" draggable="true" ondragstart="event.dataTransfer.setData('text/plain','dddd')"> 我可以拖動 </div> <img src="test.jpg" id="img"> <div class="drop"></div> <script type="text/javascript"> document.addEventListener('drag',function(event){ event.target.style.backgroundColor = 'black'; },false); document.addEventListener('dragstart',function(event){ event.target.style.backgroundColor = 'red'; },false); document.addEventListener('dragend',function(event){ event.target.style.backgroundColor = 'yellow'; },false); document.addEventListener('dragover',function(event){ event.preventDefault(); event.target.style.backgroundColor = 'blue'; },false); document.addEventListener('dragenter',function(event){ event.target.style.backgroundColor = 'green'; },false); document.addEventListener('dragleave',function(event){ event.target.style.backgroundColor = 'pink'; },false); document.addEventListener('dragexit',function(event){ event.target.style.backgroundColor = 'red' },false); document.addEventListener('drop',function(event){ event.preventDefault(); event.target.style.backgroundColor = 'white'; console.log(2); },false) </script> </body> </html>
這些事件的事件對象包含滑鼠事件的事件對象的方法與屬性。之外還存在一個dataTransfer屬性
讓元素可拖
在HTML中預設可拖的元素只有image,link及被選擇的文本。要讓其他元素可拖,需要做下麵這三件事:
1.給元素設置一個draggable屬性,並且將這個屬性的值設置為true
2.在這個元素上添加一個dragstart的事件監聽
3.在dragstart的事件監聽上通過event.DataTransfer.setData(type,value)設置拖拽數據。
<div draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')"> This text <strong>may</strong> be dragged. </div>
如果draggable屬性被禁止或者設置為false,那麼這個元素不能被拖拽。draggable屬性可以在任何屬性上設置。當一個元素設置為可拖,在這個元素上點擊或拖動滑鼠,這個元素里的文本或其他元素不會被選中。當用戶開始拖動,dragstart事件會被觸發,在dragstart事件中,你能夠通過setData()指定拖拽數據,通過setDragImage()指定圖片反饋,以及通過設置effectAllowed屬性和dropEffect屬性指定拖拽效果。拖拽數據是必須指定的,但是圖片反饋是拖拽效果不是必須的
拖拽數據
拖拽數據包含兩部分信息,分別是數據的類型和數據的值,數據的類型是字元串,數據的值也是字元串形式。 拖拽數據的類型有:text/plain,text/html,image/jpeg,text/uri-list等,還能夠自定義類型。
可以多次調用setData()方法設置多個拖拽數據。如下:
var dt = event.dataTransfer; dt.setData("application/x-bookmark",bookmarkString); dt.setData('text/uri-list','www.baidu.com'); dt.setData('text/plain','drag data');
application/x-bookmark是自定義類型。
如果通過這個方法設置新的類型的數據,那麼這個新的拖拽數據會位於拖拽數據列表的尾部,如果設置以及存在的類型的數據,那麼新的數據會覆蓋舊的數據。
通過getData()能夠得到指定類型的拖拽數據
通過clearData()能夠清除指定類型的拖拽數據
圖片反饋
圖片反饋並不是必須設置的,預設它是從拖拽目標上生成的一個半透明圖片,並且這個圖片在拖拽期間會跟著滑鼠移動。你能夠通過setDragImage(image,xOffect,yOffect)方法自定義圖片反饋。
setDragImage()接受三個參數,第一個參數表示圖片引用,第二個和第三個表示圖片左上角相對於滑鼠指針的位置。單位是像素
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>test target</title> <style type="text/css"> #drag{ width:200px; height:200px; background-color: aqua; } .drop{ width: 300px; height: 300px; background-color: antiquewhite; } </style> </head> <body> <div id="drag" draggable="true" ondragstart="event.dataTransfer.setData('text/plain','dddd')"> 我可以拖動 </div> <img src="test.jpg" id="img"> <div class="drop"></div> <script type="text/javascript"> document.addEventListener('dragstart',function(event){ event.target.style.backgroundColor = 'red'; event.dataTransfer.setDragImage(document.getElementById('img'),30,30); },false); </script> </body> </html>
拖拽效果
通過設置effectAllowed和dropEffect可以指定拖拽效果
事件對象的dataTransfer屬性
dataTransfer屬性是一個DataTransfer對象,在這個屬性中保存了拖拽操作過程中的數據,它可能保存一個或者多個數據項。這個屬性是只讀的。
dataTransfer屬性中的標準屬性
1.dropEffect
得到當前drag and drop操作的類型,或者設置給當前drag and drop 設置新的類型。這個屬性可能取值是none,copy,move,link。這屬性會影響拖拽過程中的滑鼠的顯示形式。
2.effectAllowed
這個屬性用於指定運行的拖拽操作效果,可選的值有none,all,copy,move,link,copyLink,copyMove,linkMove。預設情況這個值是all,如果要設置這個屬性的值就要在dragstart的事件處理程式里進行設置。
3.files
包含了在data transfer中的所有可用的本地文件列表,如果被拖拽操作沒有涉及文件,那麼它是一個空列表。
4.items
是一個包含了所有拖拽數據的列表。它是一個DataTransferItemList對象。
5.types
它是一個字元串數組,這個數組中包含在dragstart事件處理程式中設置的拖拽事件的類型,如果拖拽操作不存在數據,那麼他得到一個空數組。
DataTransfer屬性的標準方法
1.clearData(type):移除給定類型相關的拖拽數據。接受一個可選的參數,如果這個參數是空或者沒有指定,那麼移除所以類型的數據,如果指定的類型不存在或者data transfer中不包含數據,那麼這個方法不會產生什麼影響。
2.getData(type):得到指定類型的拖拽數據。如果指定類型的數據不存在或者data transfer中不包含數據, 得到一個空的字元串。
3.setData(type,value):設置給定類型的拖拽數據。接受兩個參數,第一個參數是類型,第二個參數是指定類型的值。 如果這個類型的值不存在,那麼在類型列表的最後添加一個新的格式,如果已經存在的,那麼在相同的位置 存在的數據被替換.
4.setDragImage(image,xoffset,yoffset):接受三個參數,第一個參數是圖片的引用,第二個和第三個參數是移動的圖片的 左上角相對滑鼠的位置。
DataTransferItemList對象
通過dataTransfer.items得到的值就是DataTransferList對象。
DataTransferItemList對象的屬性
1.length:得到拖拽數據的數量
DataTransferItemList對象的方法
1.add():向拖拽數據列表中添加一個新的拖拽數據,添加成功後返回這個新的拖拽數據。當添加一個文件到拖拽數據列表中,這個方法只接受一個文件對象作為參數。當添加一個給定 類型的字元串到拖拽數據列表中,這個方法接受兩個參數,第一個參數是數據,第二個參數是類型。
2.remove(index):從拖拽數據列表中移除指定位置的拖拽數據。這個方法接受一個表示位置的參數,如果這個參數小於0或者大於拖拽數據列表的長度,拖拽數據列表不會發生改變。
3.clear():移除拖拽數據列表中所有的拖拽數據。不需要參數。
4.DataTransferItem(index):得到指定位置上的拖拽數據。接受一個表示位置的參數, 這個方法簡寫形式是數組索引。
DataTransferItem對象
dataTransfer.items中的每一項都是DataTransferItem對象。
DataTransferItem對象的屬性
1.kind:得到拖拽數據的鍵,可能的值有file和string
2.type:得到拖拽數據的類型,是MINE type
DataTransferItem對象的方法
1.getAsFile():返回拖拽數據的文件對象。如果拖拽數據不是文件則返回null
2.getAsString(function):調用回調函數,這個回調函數將拖拽數據項的字元串形式作為它的參數
拖拽文件
要使文件能夠被拖放的一個重要步驟是定義一個放置區域。並且為放置區域添加drop,dragover和dragend事件處理程式。
當為一個元素添加drop事件的處理程式,及在dragover事件處理程式中取消瀏覽器的預設行為,那麼這個元素就是放置區域。
另外,在drag和drop操作結束之後,應用程式應該移除拖拽數據(可能是一個或者多個文件),數據的清理通常在 dragend事件處理程式中。
<div id="drop_zone" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend = "dragend_handler(event)"> <strong><Drag one or more files to this Drop Zone ...</strong> </div>
例子一,訪問文件名
function drop_handler(ev) { console.log("Drop"); ev.preventDefault(); // If dropped items aren't files, reject them var dt = ev.dataTransfer; if (dt.items) { // Use DataTransferItemList interface to access the file(s) for (var i=0; i < dt.items.length; i++) { if (dt.items[i].kind == "file") { var f = dt.items[i].getAsFile(); console.log("... file[" + i + "].name = " + f.name); } } } else { // Use DataTransfer interface to access the file(s) for (var i=0; i < dt.files.length; i++) { console.log("... file[" + i + "].name = " + dt.files[i].name); } } }
例子二,阻止瀏覽器預設行為
function dragover_handler(ev) { console.log("dragOver"); // Prevent default select and drag behavior ev.preventDefault(); }
例子三,清除數據
function dragend_handler(ev) { console.log("dragEnd"); // Remove all of the drag data var dt = ev.dataTransfer; if (dt.items) { // Use DataTransferItemList interface to remove the drag data for (var i = 0; i < dt.items.length; i++) { dt.items.remove(i); } } else { // Use DataTransfer interface to remove the drag data ev.dataTransfer.clearData(); } }