HTML5 — 让拖放变的流行起来
在?HTML5?出現(xiàn)之前,頁面元素的拖放需要監(jiān)聽 mousedown、mouseover 以及 mouseup 等一系列事件,然后改變元素的相對位置來實現(xiàn)這一效果。HTML DnD(Drag-and-Drop)API 的出現(xiàn),使得拖放變的簡單。但是由于 DnD 尚處在草案階段,各瀏覽器對其規(guī)范并未統(tǒng)一,有些事件在不同瀏覽器中會出現(xiàn)不同效果。
要使用 DnD,需要明確兩件事情,一是需要拖動的元素,二是可放置拖動元素的位置。拖放無非是將元素從一個位置拖到另一個位置。
Drag
首先我們需要指定要拖動的元素,設(shè)置方式很簡單,給該 DOM 元素設(shè)置 draggable 屬性,屬性值設(shè)置為 true。比如這樣:
<img src="images/0.jpg" draggable="true" id="img0"/>
事實上,以上代碼多此一舉了,頁面中的圖片(img)、鏈接(帶 href 的 a 標(biāo)簽)以及文本默認即為可拖動。為了統(tǒng)一,最好還是都加上該 draggable 屬性為好。draggable 屬性還有兩個值,分別是 false 和 auto,顧名思義,false 即設(shè)置為不可拖動,auto 即為瀏覽器默認值。
當(dāng)我們左鍵點擊(按下)可拖動的 DOM 元素,輕輕移動,即觸發(fā) ondragstart 事件,該事件只會觸發(fā)一次。通常我們會在 ondragstart 事件中記錄正在被拖動的元素信息(ondrop 的時候好對其進行處理)。比如 demo 中記錄了正在被拖動的元素 id:
for (var i = lis.length; i--; ) {
lis[i].ondragstart = function(e) {
e.dataTransfer.setData('id', e.target.id);
};
}
? ? ? ondragstart 事件觸發(fā)后,直到拖放事件結(jié)束,會一直觸發(fā) ondrag 事件。
Drop
其次我們需要明確被拖動元素可放置的位置,ondragover 事件規(guī)定在何處放置被拖動的數(shù)據(jù)。
默認地,無法將元素放置到其他元素中,如果需要設(shè)置允許放置,我們必須阻止對元素的默認處理方式:
var dus = document.querySelector('.dustbin');
dus.ondragover = function(e) {
e.preventDefault();
};
當(dāng)元素被拖動到某一元素上時,即會觸發(fā)后者的 ondrop 事件,如果需要正確觸發(fā) ondrop 事件,還需要取消一些 DnD 事件的默認行為:
dus.ondrop = function(e) {
// 調(diào)用 preventDefault() 來避免瀏覽器對數(shù)據(jù)的默認處理(drop 事件的默認行為是以鏈接形式打開)
e.preventDefault();
e.stopPropagation(); // 兼容ff
var id = e.dataTransfer.getData('id')
, node = document.getElementById(id);
node.parentNode.removeChild(node);
};
有些文獻中說要取消 ondragenter() 事件的默認行為,樓主在實際操作中并未發(fā)現(xiàn)這點。
事件
上面已經(jīng)提到了 DnD 中的三個事件,dragstart、dragover 以及 drop,其實 DnD 還有幾個事件,它們的發(fā)生順序是:
dragstart(drag元素) -> drag(drag元素) -> dragenter(drop元素) -> dragover(drop元素) -> dragleave(drop元素) -> drop(drop元素) -> dragend(drag元素)
不難理解,拖放事件開始時觸發(fā) ondragstart 事件,當(dāng)被拖動元素進入可放置的元素時,觸發(fā) ondragenter 事件(ondragenter 并不是在兩個元素相交時即觸發(fā),而是該被拖拽元素在目標(biāo)元素上移動一段時間后才觸發(fā)),之后一段事件會持續(xù)觸發(fā) ondragover 事件(可參考 mouseover),當(dāng)被拖動元素離開可放置元素的一瞬間,觸發(fā) ondragleave(和 ondragenter 對應(yīng)) 事件,當(dāng)松開鼠標(biāo)并且 被拖拽元素正好在可放置元素上時,觸發(fā) ondrop 事件,當(dāng)拖放事件結(jié)束時,觸發(fā) ondragend(和 ondragstart 對應(yīng)) 事件,無論拖放操作是否成功,均會觸發(fā)該事件。
dataTransfer
拖動過程中,回調(diào)函數(shù)接受的事件參數(shù),有一個 dataTransfer 屬性。它指向一個對象,包含了與拖動相關(guān)的各種信息。
dataTransfer 對象主要有兩種方法:getData() 和 setData(),需要注意的是,只有在 dragstart 以及 drop 事件中使用這兩個方法。不難想象,getData() 可以取得由 setData() 保存的值。
setData() 方法的第一個參數(shù),也是 getData() 方法唯一的一個參數(shù),是個字符串,表示保存的數(shù)據(jù)類型,取值為 ‘text’ 或 ‘URL’。IE 只定義了 ‘text’ 和 ‘URL’ 兩種有效的數(shù)據(jù)類型, 而 HTML5 則對此加以擴展,允許指定各種 MIME 類型。
在拖動文本框中的文本時,瀏覽器會自動調(diào)用 setData() 方法,將拖動的文本以 ‘text’ 格式保存在 dataTransfer 對象中,類似地,在拖放鏈接或者圖像時,會自動調(diào)用 setData() 將 URL 信息 保存,如果有需要,在 drop 事件中可以用 getData() 讀取瀏覽器保存的值。
但是這似乎并沒有什么卵用,我們在實際開發(fā)中多數(shù)還是對 DOM 的操作,于是多數(shù)情況下我們在 dragstart 事件處理程序中調(diào)用 setData(),手工保存自己要傳輸?shù)臄?shù)據(jù),然后在 drop 事件中讀取, 有點像 jQuery 的 data 事件。
dropEffect 與 effectAllowed
dropEffect 和 effectAllowed 是前面說的 dataTransfer 對象的兩個屬性,有啥用?簡單地說,有兩個用處,一是可以設(shè)置元素被拖拽時的鼠標(biāo)樣式,二是可以設(shè)置元素是否可被放置。
這里我測試了三款瀏覽器,chrome、ff 以及 uc,chrome 和 uc 表現(xiàn)相似。
一般我們將元素脫離原來的位置,鼠標(biāo)手勢會變成 “禁手”,直到元素被拖到可放置區(qū)域上。
但是 ff 不然,在 ff 中,元素在拖動的過程中不會顯示 “禁手”。
當(dāng)元素被拖到可放置區(qū)域上時,默認鼠標(biāo)手勢如下。
其實通過設(shè)置 dropEffect 和 effectAllowed 總共能設(shè)置三種鼠標(biāo)手勢(move, copy,以及 link),分別如下(move 和默認貌似一樣):
需要在 ondragstart 方法中設(shè)置 effectAllowed,在 ondragover 方法中設(shè)置 dropEffect。具體可以參考 demo代碼。
我們也可以對 dropEffect 和 effectAllowed 的值進行設(shè)定,讓某 drop 元素只能放 move 元素,或者 copy 元素等。具體可以看下這篇,HTML5魔法堂:全面理解Drag & Drop API,講的很好。取值也可以參考高程 484 頁。
總之要知道的是,DnD 并不會幫你完成 copy 或者 move 的任何操作,而是需要用戶在 DnD 過程中,記錄需要操作的對象信息,然后在 drop 事件中完成 copy 或者 move 等的操作。
Tricks
還有幾個實踐過程中發(fā)現(xiàn)的問題。
將 Demo 在 ff 中打開,圖片拖到空處,會自動在新標(biāo)簽中打開圖片,盡管我已經(jīng)在各種事件中加上了 preventDefault(),尚不清楚原因。
如果可拖拽元素,初始在一個可放置元素內(nèi)部,先把元素拖出去,再放回來,將會觸發(fā) ondrop 事件,但是 e.target 卻是被拖拽的元素。如果放置在其他元素,target 會指向被放置的元素,而不是拖拽元素。這點可以通過判斷 target 元素得到解決。關(guān)于這點可以看下 w3cschool 的這個 demo,打開控制臺,將圖片拖出去,再拖回來,控制臺會打印出錯誤,顯然代碼沒有考慮到這一點。
繼續(xù)相關(guān)文章:http://wex5.com/cn/2016/01/
本文由WeX5君整理,WeX5一款開源免費的html5開發(fā)工具,H5 App開發(fā)就用WeX5!
轉(zhuǎn)載于:https://www.cnblogs.com/huzigege/p/5148595.html
總結(jié)
以上是生活随笔為你收集整理的HTML5 — 让拖放变的流行起来的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Open*** 安装脚本
- 下一篇: HTML5本地存储之Web Storag