拖放事件
H5的拖放事件提供了多個接口:
1、drag:當元素或者選中的文本被拖動時觸發(每幾百毫秒觸發一次),應用在被拖拽元素上
2、dragend:當拖動操作結束時觸發(通過釋放鼠標按鈕或者點擊轉義鍵),應用在被拖拽元素上
3、dragenter:當一個被拖動的元素或者選中的文本進入一個有效的放置目標時觸發,應用在目標元素上
4、dragexit:當元素不再是拖動操作的直接選擇元素時觸發(很少使用)
5、dragleave:當拖動元素或者選中的文本離開有效的放置區域時觸發,應用在目標元素上
6、dragover:當元素或者選中的文本被拖動到有效放置區域上方時觸發(每幾百毫秒觸發一次),應用在目標元素上
7、dragstart:當用戶開始拖動元素或者拖動選中文本時觸發,應用在被拖拽元素上
8、drop:當元素或選中的文本在有效區域放置時觸發,應用在目標元素上
<div class="dropzone"> <div id="draggable" draggable="true" ondragstart="event.dataTransfer.setData('text/plain',null)"> <!--為兼容IE dataTransfer只能放在這里--> This div is draggable </div> </div> <div class="dropzone"></div> <div class="dropzone"></div> <div class="dropzone"></div>
var dragged; /* 事件在拖拽元素上觸發 */ document.addEventListener("drag", function( event ) { }, false); /* 事件在拖拽元素上觸發 */ document.addEventListener("dragstart", function( event ) { // 存儲相關的拖拽元素 dragged = event.target; // 設置拖拽元素的透明度 event.target.style.opacity = .5; }, false); /* 事件在拖拽元素上觸發 */ document.addEventListener("dragend", function( event ) { // 重設透明度 event.target.style.opacity = ""; }, false); /* 事件在目標區域觸發 */ document.addEventListener("dragover", function( event ) { // 默認情況下是無法允許一個元素放置在另一個元素上的,要放置必須阻止默認行為 event.preventDefault(); }, false); /* 事件在目標區域觸發 */ document.addEventListener("dragenter", function( event ) { // 當拖拽元素進入潛在放置區域時,高亮處理 if ( event.target.className == "dropzone" ) { event.target.style.background = "purple"; } }, false); /* 事件在目標區域觸發 */ document.addEventListener("dragleave", function( event ) { // 當拖拽元素離開潛在放置區域時重置該目標區域的背景 if ( event.target.className == "dropzone" ) { event.target.style.background = ""; } }, false); document.addEventListener("drop", function( event ) { // 阻止默認行為(drop的默認處理方式是當初鏈接處理) event.preventDefault(); // 把拖拽元素移入目標區域 //這里要經過兩步處理 // 1、先把拖拽元素從原父元素中刪除(這步不是必須的) ///2、然后再添加到目標區域 if ( event.target.className == "dropzone" ) { event.target.style.background = ""; dragged.parentNode.removeChild( dragged ); event.target.appendChild( dragged ); } }, false);
event.dataTransfer
在進行拖放操作時,DataTransfer 對象用來保存被拖動的數據。它可以保存一項或多項數據、一種或者多種數據類型
這個對象在所有的拖動事件屬性dataTransfer 都是可用的,但是不能單獨創建。
dataTransfer屬性(比較多,簡單羅列幾個)
dropEffect:
設置實際的放置效果,它應該始終設置成 effectAllowed 的可能值之一
可能的值:
copy: 復制到新的位置 move: 移動到新的位置. link: 建立一個源位置到新位置的鏈接. none: 禁止放置(禁止任何操作).
設置其他值會導致拖放失敗
effectAllowed:
用來指定拖動時被允許的效果
可能的值:
copy: 復制到新的位置. move:移動到新的位置 . link:建立一個源位置到新位置的鏈接. copyLink: 允許復制或者鏈接. copyMove: 允許復制或者移動. linkMove: 允許鏈接或者移動. all: 允許所有的操作. none: 禁止所有操作. uninitialized: 缺省值(默認值), 相當於 all.
設置其他值會導致拖放失敗
items:
拖拽的數據集合
types:
該屬性返回一個DOMStringList對象,該對象包括了存入dataTransfer中數據的所有類型,返回值是一個數組
dataTransfer方法(比較多,簡單羅列幾個)
setData()
將指定格式的數據賦值給dataTransfer對象,參數format定義數據的格式也就是數據的類型,data為待賦值的數據,有點像jquery里面的data
如果指定的數據類型不存在,它將添加到的末尾,這樣類型列表中的最后一個項目將是新的格式。如果已經存在的數據類型,替換相同的位置的現有數據。就是,當更換相同類型的數據時,不會更改類型列表的順序。
getData(format)
從dataTransfer對象中獲取指定格式的數據,format代表數據格式,如果給定類型的數據不存在或者數據轉存(data transfer)沒有包涵數據,方法將返回一個空字符串。
這個數據將僅僅在放置動作發生時在drop時間中是可用的
clearData([format])
從dataTransfer對象中刪除指定格式的數據,參數可選,若不給出,則為刪除對象中所有的數據。
addElement(element)
設置拖動源。通常不需要改變這項,如果修改將會影響拖動的那個節點和dragend事件的觸發。默認目標是被拖動的節點。
setDragImage(image,x,y)
設置拖放操作的自定義圖標。其中element設置自定義圖標,x設置圖標與鼠標在水平方向上的距離,y設置圖標與鼠標在垂直方向上的距離。
大多數情況下,這項不用設置,因為被拖動的節點被創建成默認圖片。
參數
image
要用作拖動反饋圖像元素
x
圖像內的水平偏移量.
y
圖像內的垂直偏移量.
案例
div>div{ display:inline-block; padding: 10px; background-color: #aaa; margin: 3px; }
<div style="width:600px;border:1px solid black;"> <h2>可將喜歡的項目拖到收藏夾</h2> <div draggable="true" ondragstart="dsHandler(event);">勿忘心安</div> <div draggable="true" ondragstart="dsHandler(event);">照顧自己</div> <div draggable="true" ondragstart="dsHandler(event);">Number 9</div> <div draggable="true" ondragstart="dsHandler(event);">崇拜</div> </div> <div id="dest" style="width:400px;height:400px;border:1px solid black;float:left;"> <h2 ondragleave="return false;">收藏夾</h2> </div> <div id="gb" draggable="false" style="width:100px;height:100px;border:1px solid red;float:left;">我是垃圾桶</div>
var dest = document.getElementById("dest"); var dsHandler = function (evt){ evt.dataTransfer.setData("text/plain","<item>"+evt.target.innerHTML); } dest.ondrop = function(evt){ var text = evt.dataTransfer.getData("text/plain"); if(text.indexOf("<item>") == 0){ var newEle = document.createElement("div"); newEle.id = new Date().getUTCMilliseconds(); newEle.innerHTML = text.substring(6); newEle.draggable = "true"; newEle.ondragstart = function(evt){ evt.dataTransfer.setData("text/plain","<remove>"+newEle.id); } dest.appendChild(newEle); } } document.getElementById("gb").ondrop = function(evt){ var id = evt.dataTransfer.getData("text/plain"); if(id.indexOf("<remove>") == 0){ var target = document.getElementById(id.substring(8)); dest.removeChild(target); } } document.ondragover = function(evt){ return false; } document.ondrop = function(evt){ return false; }
案例來自:https://my.oschina.net/jiangli0502/blog/179197
補充:
text/html & text/plain的區別
Content-Type:用於定義用戶的瀏覽器或相關設備如何顯示將要加載的數據,或者如何處理將要加載的數據
MIME:MIME類型就是設定某種擴展名的文件用一種應用程序來打開的方式類型,當該擴展名文件被訪問的時候,瀏覽器會自動使用指定應用程序來打開。多用於指定一些客戶端自定義的文件名,以及一些媒體文件打開方式。
text/html的意思是將文件的content-type設置為text/html的形式,瀏覽器在獲取到這種文件時會自動調用html的解析器對文件進行相應的處理。
text/plain的意思是將文件設置為純文本的形式,瀏覽器在獲取到這種文件時並不會對其進行處理。
參考資料
https://developer.mozilla.org/en-US/docs/Web/Events/drag
https://developer.mozilla.org/zh-CN/docs/Web/API/DataTransfer