Vue實(shí)現(xiàn)DOM元素拖放互換位置示例
一、拖放和釋放
HTML 拖放接口使得 web 應(yīng)用能夠在網(wǎng)頁(yè)中拖放文件。這里將介紹了 web 應(yīng)用如何接受從底層平臺(tái)的文件管理器拖動(dòng)DOM的操作。
拖放的主要步驟是為 drop 事件定義一個(gè)釋放區(qū)(釋放文件的目標(biāo)元素) 和為dragover事件定義一個(gè)事件處理程序。
觸發(fā) drop 事件的目標(biāo)元素需要一個(gè)ondrop 事件處理函數(shù)。下面這一段代碼以一個(gè) <div> 元素為例展示了這些工作是如何完成的:
<div id="drop_zone" ondrop="dropHandler(event);"> <p>Drag one or more files to this Drop Zone ...</p> </div>
一般來(lái)說(shuō),在實(shí)際應(yīng)用中需要定義一個(gè) dragover 事件的處理函數(shù)并在其中加入關(guān)閉瀏覽器默認(rèn)拖放行為的代碼。需要定義一個(gè) ondragover 事件處理函數(shù):
<div id="drop_zone" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);"> <p>Drag one or more files to this Drop Zone ...</p> </div>
二、可拖拽屬性
在一個(gè)網(wǎng)頁(yè)中,有幾種特定情況會(huì)使用默認(rèn)拖拽行為,其中包括拖拽選中文本、拖拽圖像和拖拽鏈接。當(dāng)一個(gè)圖像或鏈接被拖拽時(shí),圖像或鏈接的 URL 被設(shè)定為拖拽數(shù)據(jù)。對(duì)于其他元素,只當(dāng)它們是被選中的一部分時(shí),才會(huì)觸發(fā)默認(rèn)拖拽行為。如果想看看拖拽實(shí)際的樣子,可以選中網(wǎng)頁(yè)的一部分,然后按住鼠標(biāo),拖動(dòng)選中的目標(biāo)。選中的部分根據(jù)系統(tǒng)的不同會(huì)有不同的渲染效果,并在拖拽時(shí)跟隨著鼠標(biāo)指針。然而,這只是默認(rèn)拖拽行為的效果,此時(shí)沒(méi)有監(jiān)聽(tīng)程序調(diào)整拖拽數(shù)據(jù)。
在 HTML 中,除了圖像、鏈接和選擇的文本默認(rèn)的可拖拽行為之外,其他元素在默認(rèn)情況下是不可拖拽的。
要使其他的 HTML 元素可拖拽,必須做三件事:
- 將想要拖拽的元素的 draggable 屬性設(shè)置成 draggable="true"。
- 為 [dragstart]事件添加一個(gè)監(jiān)聽(tīng)程序。
- 在上一步定義的監(jiān)聽(tīng)程序中 設(shè)置拖拽數(shù)據(jù)。
屬性 draggable 設(shè)置為 "true",所以這個(gè)元素變成可拖拽的。如果該屬性被省略或被設(shè)置為 "false",則該元素將不可拖拽,此時(shí)拖拽只會(huì)選中文本。
draggable 屬性可在任意元素上設(shè)置,包括圖像和鏈接。然而,對(duì)于后兩者,該屬性的默認(rèn)值是 true,所以你只會(huì)在禁用這二者的拖拽時(shí)使用到 draggable 屬性,將其設(shè)置為 false。
三、DataTransfer
DataTransfer 對(duì)象用于保存拖動(dòng)并放下(drag and drop)過(guò)程中的數(shù)據(jù)。它可以保存一項(xiàng)或多項(xiàng)數(shù)據(jù),這些數(shù)據(jù)項(xiàng)可以是一種或者多種數(shù)據(jù)類(lèi)型。
3.1 屬性
dropEffect | 獲取當(dāng)前選定的拖放操作類(lèi)型或者設(shè)置的為一個(gè)新的類(lèi)型。值必須為 none, copy, link 或 move。 |
effectAllowed | 提供所有可用的操作類(lèi)型。必須是 none, copy, copyLink, copyMove, link, linkMove, move, all or uninitialized 之一。 |
files | 包含數(shù)據(jù)傳輸中可用的所有本地文件的列表。如果拖動(dòng)操作不涉及拖動(dòng)文件,則此屬性為空列表。 |
items | 提供一個(gè)包含所有拖動(dòng)數(shù)據(jù)列表的 DataTransferItemList 對(duì)象。 |
types | 一個(gè)提供 dragstart 事件中設(shè)置的格式的 strings 數(shù)組。 |
3.2 方法
clearData() | 刪除與給定類(lèi)型關(guān)聯(lián)的數(shù)據(jù)。類(lèi)型參數(shù)是可選的。如果類(lèi)型為空或未指定,則刪除與所有類(lèi)型關(guān)聯(lián)的數(shù)據(jù)。如果指定類(lèi)型的數(shù)據(jù)不存在,或者 data transfer 中不包含任何數(shù)據(jù),則該方法不會(huì)產(chǎn)生任何效果。 |
getData() | 檢索給定類(lèi)型的數(shù)據(jù),如果該類(lèi)型的數(shù)據(jù)不存在或 data transfer 不包含數(shù)據(jù),則返回空字符串。 |
setData() | 設(shè)置給定類(lèi)型的數(shù)據(jù)。如果該類(lèi)型的數(shù)據(jù)不存在,則將其添加到末尾,以便類(lèi)型列表中的最后一項(xiàng)將是新的格式。如果該類(lèi)型的數(shù)據(jù)已經(jīng)存在,則在相同位置替換現(xiàn)有數(shù)據(jù)。 |
setDragImage() | 用于設(shè)置自定義的拖動(dòng)圖像。 |
四、DataTransferItem
DataTransferItem 描述了一個(gè)拖拽項(xiàng)。在一個(gè)拖拽操作*中,*每一個(gè) drag event 都有一個(gè)dataTransfer 屬性,它包含一個(gè)存有拖拽數(shù)據(jù)的 list ,其中每一項(xiàng)都是一個(gè) DataTransferItem 。
4.1 屬性
kind | 拖拽項(xiàng)的種類(lèi),string 或是 file。 |
type | 拖拽項(xiàng)的類(lèi)型,一般是一個(gè) MIME 類(lèi)型。 |
4.2 方法
getAsFile() | 返回一個(gè)關(guān)聯(lián)拖拽項(xiàng)的 File 對(duì)象(當(dāng)拖拽項(xiàng)不是一個(gè)文件時(shí)返回 null)。 |
getAsString() | 使用拖拽項(xiàng)的字符串作為參數(shù)執(zhí)行指定回調(diào)函數(shù)。 |
webkitGetAsEntry() | 返回一個(gè)基于 FileSystemEntry 的對(duì)象來(lái)表示文件系統(tǒng)中選中的項(xiàng)目。通常是返回一個(gè)FileSystemFileEntry 或是 FileSystemDirectoryEntry 對(duì)象。 |
五、DataTransferItemList
5.1 屬性
length | 無(wú)符號(hào)長(zhǎng)整型 :列表中拖動(dòng)項(xiàng)的數(shù)量。 |
5.2 方法
add() | 向拖動(dòng)項(xiàng)列表中添加新項(xiàng) (File對(duì)象或string),該方法返回一個(gè) DataTransferItem 對(duì)象。 |
remove() | 根據(jù)索引刪除拖動(dòng)項(xiàng)列表中的對(duì)象。 |
clear() | 清空拖動(dòng)項(xiàng)列表。 |
DataTransferItem() | 取值方法:返回給定下標(biāo)的DataTransferItem對(duì)象。 |
六、Event事件
drag | 在用戶(hù)拖動(dòng)元素或選擇的文本時(shí),每隔幾百毫秒就會(huì)被觸發(fā)一次。 |
dragend | 在拖放操作結(jié)束時(shí)觸發(fā)(通過(guò)釋放鼠標(biāo)按鈕或單擊 escape 鍵)。 |
dragenter | 在可拖動(dòng)的元素或者被選擇的文本進(jìn)入一個(gè)有效的放置目標(biāo)時(shí)觸發(fā)。目標(biāo)對(duì)象是用戶(hù)直接選擇的范圍(由用戶(hù)直接指示作為放置目標(biāo)的元素),或者 <body> 元素。 |
dragleave | 在拖動(dòng)的元素或選中的文本離開(kāi)一個(gè)有效的放置目標(biāo)時(shí)被觸發(fā)。 |
dragover | 在可拖動(dòng)的元素或者被選擇的文本被拖進(jìn)一個(gè)有效的放置目標(biāo)時(shí)(每幾百毫秒)觸發(fā)。該事件在放置目標(biāo)上觸發(fā)。 |
dragstart | 在用戶(hù)開(kāi)始拖動(dòng)元素或被選擇的文本時(shí)調(diào)用。 |
drop | 在元素或選中的文本被放置在有效的放置目標(biāo)上時(shí)被觸發(fā)。 |
七、實(shí)例
在通過(guò)上述的了解,咱們已經(jīng)知道JS拖拽功能的相關(guān)接口,這次我們將通過(guò)它們來(lái)實(shí)現(xiàn)元素的位置調(diào)換。如下圖,我們將時(shí)間從亂序中,移動(dòng)為正常排序。

7.1 html代碼
由于drag Event綁定在el-tag上無(wú)效,這里外面包裹層div來(lái)實(shí)現(xiàn)元素的拖拽事件綁定。
<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事件將不會(huì)被觸發(fā)。
在第三節(jié),已講解了dataTransfer屬性和方法,我們可能通過(guò)它進(jìn)行數(shù)據(jù)的傳遞。如dragstartEvent()函數(shù)中將被拖拽元素的索引,通過(guò)setData存儲(chǔ)到起來(lái),在dragdropEvent()事件執(zhí)行后,再通過(guò)getData獲取被拖拽元素的索引。
在將被拖拽元素插入到新位置前,我們需要通過(guò)splice將原位置的刪除,再通過(guò)splice將其插入新的位置,代碼如下:
<script>
export default {
data(){
return {
recordList: ['08:30', '22:45', '09:00', '23:30', '09:00', '04:30']
}
},
methods: {
/**
* 開(kāi)始拖拉元素的值 索引位置
*/
dragstartEvent(e, i){
e.dataTransfer.setData('start', i);
},
/**
* 元素經(jīng)過(guò)某元素位置時(shí),執(zhí)行事件
*/
dragoverEvent(e, i){
e.preventDefault();
},
/**
* 放開(kāi)元素時(shí)執(zhí)行
*/
dragdropEvent(e, i){
let startIndex = e.dataTransfer.getData('start');
if(startIndex||0==startIndex){
//記錄被拖動(dòng)元素內(nèi)容
let startVal = this.recordList[startIndex];
//刪除被拖動(dòng)位置元素
this.recordList.splice(startIndex, 1);
//將被拖動(dòng)元素插入數(shù)組指定位置
this.recordList.splice(i, 0, startVal);
//清除記錄數(shù)據(jù)
e.dataTransfer.clearData();
}
},
}
}
</script>
通過(guò)這個(gè)小案例,在Vue中將元素變成可拖拽的,實(shí)現(xiàn)了以拖拽方式更換了元素的位置,希望對(duì)大家有所幫助。
到此這篇關(guān)于Vue實(shí)現(xiàn)DOM元素拖放互換位置示例的文章就介紹到這了,更多相關(guān)Vue DOM元素拖放互換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解mpvue小程序中怎么引入iconfont字體圖標(biāo)
這篇文章主要介紹了詳解mpvue小程序中怎么引入iconfont字體圖標(biāo),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10
vue awesome swiper異步加載數(shù)據(jù)出現(xiàn)的bug問(wèn)題
這篇文章主要介紹了vue awesome swiper異步加載數(shù)據(jù)出現(xiàn)的bug問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07
Vue實(shí)例創(chuàng)建和掛載的詳細(xì)過(guò)程
在 Vue.js 中,實(shí)例的掛載是一個(gè)非常重要的過(guò)程,它決定了 Vue 實(shí)例如何與 DOM 進(jìn)行交互,通過(guò)分析 Vue 源碼,特別是 Vue 的構(gòu)建函數(shù)和生命周期,我們可以了解掛載過(guò)程的詳細(xì)步驟,需要的朋友可以參考下2024-11-11
Ant design vue中的聯(lián)動(dòng)選擇取消操作
這篇文章主要介紹了Ant design vue中的聯(lián)動(dòng)選擇取消操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
vue實(shí)現(xiàn)導(dǎo)出word文檔功能實(shí)例(含多張圖片)
項(xiàng)目需要導(dǎo)出word,于是乎又是查閱資料,然后自己寫(xiě),下面這篇文章主要給大家介紹了關(guān)于vue實(shí)現(xiàn)導(dǎo)出word文檔功能(含多張圖片)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09
vue原理Compile從新建實(shí)例到結(jié)束流程源碼
這篇文章主要為大家介紹了vue原理Compile從新建實(shí)例到結(jié)束流程源碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Vue無(wú)法對(duì)iframe進(jìn)行緩存的解決方案
項(xiàng)目采用的若依框架,但系統(tǒng)中會(huì)嵌入大屏、報(bào)表頁(yè)面,是使用iframe來(lái)實(shí)現(xiàn)的,若依框架的菜單管理中提供了緩存功能,是使用keep-alive實(shí)現(xiàn)的,但對(duì)于iframe頁(yè)面并不生效,所以本文介紹了關(guān)于Vue無(wú)法對(duì)iframe進(jìn)行緩存的解決方案記錄,需要的朋友可以參考下2024-12-12

