簡介
拖放是一種常見的特性,即抓取物件以後拖曳到另一個位置。
在 HTML5 中,拖放是標準的一部分,任何元素都能夠拖放。
先點擊一個小範例:在使用者開始拖曳
元素時執行 JavaScript
<p draggable="true" ondragstart="myFunction(event)">拖动我!</p>
提示: 連結和圖片預設是可拖曳的,不需要 draggable 屬性。
定義與使用
在拖放的過程中會觸發以下事件:
在拖曳目標上觸發事件 (來源元素):
ondragstart - 使用者開始拖曳元素時觸發
ond - 元素正在拖曳元素時觸發
ond - 元素正在拖曳元素當觸發拖曳的物件在另一個物件容器範圍內拖曳時觸發此事件
ondragleave - 當被滑鼠拖曳的物件離開其容器範圍內時觸發此事件
ondrop - 在一個拖曳過程中,釋放滑鼠鍵時觸發此事件
瀏覽器支援
Internet Explorer 9+, Firefox, Opera, Chrome, 和Safari 支援拖曳。
注意:Safari 5.1.2不支援拖曳;在拖曳元素時,每隔 350 毫秒會觸發 ondragover 事件。
實例
先貼程式碼,再逐一解釋:
<!DOCTYPE html> <html> <head> <title>HTML5拖拽</title> <meta charset="utf-8"> <style> #div1 {width:350px;height:70px;padding:10px;border:1px solid #aaaaaa;} </style> </head> <body> <p>拖动img_w3slogo.gif图片到矩形框中:</p> <div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div> <br> <img id="drag1" src="images/img_w3slogo.gif" draggable="true" ondragstart="drag(event)" width="300" height="56"> <script> function allowDrop(ev){ ev.preventDefault(); } function drag(ev){ ev.dataTransfer.setData("Text",ev.target.id); } function drop(ev){ ev.preventDefault(); var data=ev.dataTransfer.getData("Text"); ev.target.appendChild(document.getElementById(data)); } </script> </body> </html>
拖曳前的頁面效果為:
下面分別來解析下上面程式碼的意思。 設定元素可拖放首先,為了使元素可拖動,把draggable 屬性設為true :
<img draggable="true">
拖曳什麼- ondragstart 和setData()
然後,規定當元素被拖曳時,會發生什麼。
在上面的範例中,ondragstart 屬性呼叫了一個函數,drag(event),它規定了被拖曳的資料。
dataTransfer.setData() 方法設定被拖曳資料的資料型別和值:
function drag(ev) { ev.dataTransfer.setData("Text",ev.target.id); }
在這個範例中,資料型別是 "Text",值是可拖曳元素的 id ("drag1")。
放到何處 - ondragover
ondragover 事件規定在何處放置被拖曳的資料。
默認地,無法將資料/元素放置到其他元素中。如果需要設定允許放置,我們必須阻止對元素的預設處理方式。
這要透過呼叫 ondragover 事件的 event.preventDefault() 方法:
event.preventDefault()
進行放置 - ondrop
當放置被拖曳資料時,會發生 drop 事件。
在上面的例子中,ondrop 屬性呼叫了一個函數,drop(event):
function drop(ev) { ev.preventDefault(); var data=ev.dataTransfer.getData("Text"); ev.target.appendChild(document.getElementById(data)); }
程式碼解釋:
呼叫preventDefault() 來避免瀏覽器對資料的預設處理(drop 事件的預設行為是以連結形式開啟)
透過dataTransfer.getData("Text") 方法獲得被拖曳的資料。此方法將傳回在 setData() 方法中設定為相同類型的任何資料。
被拖曳資料是被拖曳元素的id ("drag1")
把被拖曳元素追加到放置元素(目標元素)中
實現的結果如圖:
dataTransfer在操作的過程中,我們可以使用dataTransfer物件來傳輸數據,以便在拖曳操作結束的時候對資料進行其他的操作。 物件屬性:dropEffect:設定或傳回拖放目標上允許發生的拖放行為。如果此處設定的拖放行為不再effectAllowed屬性設定的多種拖放行為之內,拖放操作將會失敗。此屬性值只允許為「null」、「copy」、「link」和「move」四值之一。
effectAllowed:設定或傳回被拖曳元素允許發生的拖曳行為。此屬性值可設為「none」、「copy」、「copyLink」、「copyMove」、「link」、「linkMove」、「move」、「all」和「uninitialized」。
items:此屬性傳回DataTransferItems對象,該物件代表了拖曳資料。
types:此屬性傳回一個DOMStringList對象,該物件包含了存入dataTransfer中資料的所有類型。
對象方法:
setData(format,data):將指定格式的資料賦值給dataTransfer對象,參數format定義資料的格式也就是資料的類型,data為待賦值的資料
getData(format):從資料的類型,data為待賦值的資料
getData(format):從資料的類型,data為待賦值的資料
getData(format):從資料的類型,data為待賦值的資料
getData(format):從dataTransfer物件中取得指定格式的數據,format代表數據格式,data為數據。
clearData([format]):從dataTransfer物件中刪除指定格式的數據,參數可選,若不給出,則為刪除物件中所有的資料。
addElement(element):新增自訂圖示
setDragImage(element,x,y):设置拖放操作的自定义图标。其中element设置自定义图标,x设置图标与鼠标在水平方向上的距离,y设置图标与鼠标在垂直方向上的距离。
Identify what is draggable
function dragstart_handler(ev) { console.log("dragStart"); // Add the target element's id to the data transfer object ev.dataTransfer.setData("text/plain", ev.target.id); } <body> <p id="p1" draggable="true" ondragstart="dragstart_handler(event);">This element is draggable.</p> </body>
Define the drag's data
function dragstart_handler(ev) { // Add the drag data ev.dataTransfer.setData("text/plain", ev.target.id); ev.dataTransfer.setData("text/html", "<p>Example paragraph</p>"); ev.dataTransfer.setData("text/uri-list", "http://developer.mozilla.org"); }
Define the drag image
function dragstart_handler(ev) { // Create an image and then use it for the drag image. // NOTE: change "example.gif" to an existing image or the image // will not be created and the default drag image will be used. var img = new Image(); img.src = 'example.gif'; ev.dataTransfer.setDragImage(img, 10, 10); }
Define the drag effect
function dragstart_handler(ev) { // Set the drag effect to copy ev.dataTransfer.dropEffect = "copy"; }
Define a drop zone
function dragover_handler(ev) { ev.preventDefault(); // Set the dropEffect to move ev.dataTransfer.dropEffect = "move" } function drop_handler(ev) { ev.preventDefault(); // Get the id of the target and add the moved element to the target's DOM var data = ev.dataTransfer.getData("text"); ev.target.appendChild(document.getElementById(data)); } <body> <div id="target" ondrop="drop_handler(event);" ondragover="dragover_handler(event);">Drop Zone</div> </body>
火狐浏览器拖拽问题
但是进行到这儿在火狐浏览器中发现一个问题:
html5的拖拽,用了preventDefault防止弹出新页面,但在火狐下不管用?
解决办法:
document.body.ondrop = function (event) { event.preventDefault(); event.stopPropagation(); }
更多HTML5 拖放(Drag 和 Drop)详解与实例相关文章请关注PHP中文网!