Vue實現DOM元素拖放互換位置示例
一、拖放和釋放
HTML 拖放接口使得 web 應用能夠在網頁中拖放文件。這里將介紹了 web 應用如何接受從底層平臺的文件管理器拖動DOM的操作。
拖放的主要步驟是為 drop 事件定義一個釋放區(qū)(釋放文件的目標元素) 和為dragover事件定義一個事件處理程序。
觸發(fā) drop 事件的目標元素需要一個ondrop 事件處理函數。下面這一段代碼以一個 <div> 元素為例展示了這些工作是如何完成的:
<div id="drop_zone" ondrop="dropHandler(event);"> <p>Drag one or more files to this Drop Zone ...</p> </div>
一般來說,在實際應用中需要定義一個 dragover 事件的處理函數并在其中加入關閉瀏覽器默認拖放行為的代碼。需要定義一個 ondragover 事件處理函數:
<div id="drop_zone" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);"> <p>Drag one or more files to this Drop Zone ...</p> </div>
二、可拖拽屬性
在一個網頁中,有幾種特定情況會使用默認拖拽行為,其中包括拖拽選中文本、拖拽圖像和拖拽鏈接。當一個圖像或鏈接被拖拽時,圖像或鏈接的 URL 被設定為拖拽數據。對于其他元素,只當它們是被選中的一部分時,才會觸發(fā)默認拖拽行為。如果想看看拖拽實際的樣子,可以選中網頁的一部分,然后按住鼠標,拖動選中的目標。選中的部分根據系統(tǒng)的不同會有不同的渲染效果,并在拖拽時跟隨著鼠標指針。然而,這只是默認拖拽行為的效果,此時沒有監(jiān)聽程序調整拖拽數據。
在 HTML 中,除了圖像、鏈接和選擇的文本默認的可拖拽行為之外,其他元素在默認情況下是不可拖拽的。
要使其他的 HTML 元素可拖拽,必須做三件事:
- 將想要拖拽的元素的 draggable 屬性設置成 draggable="true"。
- 為 [dragstart]事件添加一個監(jiān)聽程序。
- 在上一步定義的監(jiān)聽程序中 設置拖拽數據。
屬性 draggable 設置為 "true",所以這個元素變成可拖拽的。如果該屬性被省略或被設置為 "false",則該元素將不可拖拽,此時拖拽只會選中文本。
draggable 屬性可在任意元素上設置,包括圖像和鏈接。然而,對于后兩者,該屬性的默認值是 true,所以你只會在禁用這二者的拖拽時使用到 draggable 屬性,將其設置為 false。
三、DataTransfer
DataTransfer 對象用于保存拖動并放下(drag and drop)過程中的數據。它可以保存一項或多項數據,這些數據項可以是一種或者多種數據類型。
3.1 屬性
dropEffect | 獲取當前選定的拖放操作類型或者設置的為一個新的類型。值必須為 none, copy, link 或 move。 |
effectAllowed | 提供所有可用的操作類型。必須是 none, copy, copyLink, copyMove, link, linkMove, move, all or uninitialized 之一。 |
files | 包含數據傳輸中可用的所有本地文件的列表。如果拖動操作不涉及拖動文件,則此屬性為空列表。 |
items | 提供一個包含所有拖動數據列表的 DataTransferItemList 對象。 |
types | 一個提供 dragstart 事件中設置的格式的 strings 數組。 |
3.2 方法
clearData() | 刪除與給定類型關聯(lián)的數據。類型參數是可選的。如果類型為空或未指定,則刪除與所有類型關聯(lián)的數據。如果指定類型的數據不存在,或者 data transfer 中不包含任何數據,則該方法不會產生任何效果。 |
getData() | 檢索給定類型的數據,如果該類型的數據不存在或 data transfer 不包含數據,則返回空字符串。 |
setData() | 設置給定類型的數據。如果該類型的數據不存在,則將其添加到末尾,以便類型列表中的最后一項將是新的格式。如果該類型的數據已經存在,則在相同位置替換現有數據。 |
setDragImage() | 用于設置自定義的拖動圖像。 |
四、DataTransferItem
DataTransferItem 描述了一個拖拽項。在一個拖拽操作*中,*每一個 drag event 都有一個dataTransfer 屬性,它包含一個存有拖拽數據的 list ,其中每一項都是一個 DataTransferItem 。
4.1 屬性
kind | 拖拽項的種類,string 或是 file。 |
type | 拖拽項的類型,一般是一個 MIME 類型。 |
4.2 方法
getAsFile() | 返回一個關聯(lián)拖拽項的 File 對象(當拖拽項不是一個文件時返回 null)。 |
getAsString() | 使用拖拽項的字符串作為參數執(zhí)行指定回調函數。 |
webkitGetAsEntry() | 返回一個基于 FileSystemEntry 的對象來表示文件系統(tǒng)中選中的項目。通常是返回一個FileSystemFileEntry 或是 FileSystemDirectoryEntry 對象。 |
五、DataTransferItemList
5.1 屬性
length | 無符號長整型 :列表中拖動項的數量。 |
5.2 方法
add() | 向拖動項列表中添加新項 (File對象或string),該方法返回一個 DataTransferItem 對象。 |
remove() | 根據索引刪除拖動項列表中的對象。 |
clear() | 清空拖動項列表。 |
DataTransferItem() | 取值方法:返回給定下標的DataTransferItem對象。 |
六、Event事件
drag | 在用戶拖動元素或選擇的文本時,每隔幾百毫秒就會被觸發(fā)一次。 |
dragend | 在拖放操作結束時觸發(fā)(通過釋放鼠標按鈕或單擊 escape 鍵)。 |
dragenter | 在可拖動的元素或者被選擇的文本進入一個有效的放置目標時觸發(fā)。目標對象是用戶直接選擇的范圍(由用戶直接指示作為放置目標的元素),或者 <body> 元素。 |
dragleave | 在拖動的元素或選中的文本離開一個有效的放置目標時被觸發(fā)。 |
dragover | 在可拖動的元素或者被選擇的文本被拖進一個有效的放置目標時(每幾百毫秒)觸發(fā)。該事件在放置目標上觸發(fā)。 |
dragstart | 在用戶開始拖動元素或被選擇的文本時調用。 |
drop | 在元素或選中的文本被放置在有效的放置目標上時被觸發(fā)。 |
七、實例
在通過上述的了解,咱們已經知道JS拖拽功能的相關接口,這次我們將通過它們來實現元素的位置調換。如下圖,我們將時間從亂序中,移動為正常排序。
7.1 html代碼
由于drag Event綁定在el-tag上無效,這里外面包裹層div來實現元素的拖拽事件綁定。
<div @dragstart="dragstartEvent($event, index)" @dragover="dragoverEvent($event, index)" @drop="dragdropEvent($event, index)" v-for="(tag, index) in recordList" :key="tag" style="display: inline-block;"> <el-tag closable @close="removeTagEvent(tag)" type="info" draggable>{{tag}}</el-tag> </div>
7.2 JS代碼
這里需要注意的是,drop事件想要被觸發(fā),必須綁定dragover事件,并在dragover事件中執(zhí)行e.preventDefault()。未綁定dragover事件,則drop事件將不會被觸發(fā)。
在第三節(jié),已講解了dataTransfer屬性和方法,我們可能通過它進行數據的傳遞。如dragstartEvent()函數中將被拖拽元素的索引,通過setData存儲到起來,在dragdropEvent()事件執(zhí)行后,再通過getData獲取被拖拽元素的索引。
在將被拖拽元素插入到新位置前,我們需要通過splice將原位置的刪除,再通過splice將其插入新的位置,代碼如下:
<script> export default { data(){ return { recordList: ['08:30', '22:45', '09:00', '23:30', '09:00', '04:30'] } }, methods: { /** * 開始拖拉元素的值 索引位置 */ dragstartEvent(e, i){ e.dataTransfer.setData('start', i); }, /** * 元素經過某元素位置時,執(zhí)行事件 */ dragoverEvent(e, i){ e.preventDefault(); }, /** * 放開元素時執(zhí)行 */ dragdropEvent(e, i){ let startIndex = e.dataTransfer.getData('start'); if(startIndex||0==startIndex){ //記錄被拖動元素內容 let startVal = this.recordList[startIndex]; //刪除被拖動位置元素 this.recordList.splice(startIndex, 1); //將被拖動元素插入數組指定位置 this.recordList.splice(i, 0, startVal); //清除記錄數據 e.dataTransfer.clearData(); } }, } } </script>
通過這個小案例,在Vue中將元素變成可拖拽的,實現了以拖拽方式更換了元素的位置,希望對大家有所幫助。
到此這篇關于Vue實現DOM元素拖放互換位置示例的文章就介紹到這了,更多相關Vue DOM元素拖放互換內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vant-list組件觸發(fā)多次onload事件導致數據亂序的解決方案
這篇文章主要介紹了vant-list組件觸發(fā)多次onload事件導致數據亂序的解決方案2023-01-01vue 解決setTimeOut和setInterval函數無效報錯的問題
這篇文章主要介紹了vue 解決setTimeOut和setInterval函數無效報錯的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07