首頁 > 軟體

Vue實現DOM元素拖放互換位置範例

2023-01-20 14:00:10

一、拖放和釋放

HTML 拖放介面使得 web 應用能夠在網頁中拖放檔案。這裡將介紹了 web 應用如何接受從底層平臺的檔案管理器拖動DOM的操作。

拖放的主要步驟是為 drop 事件定義一個釋放區(釋放檔案的目標元素) 和為dragover事件定義一個事件處理程式。

觸發 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 被設定為拖拽資料。對於其他元素,只當它們是被選中的一部分時,才會觸發預設拖拽行為。如果想看看拖拽實際的樣子,可以選中網頁的一部分,然後按住滑鼠,拖動選中的目標。選中的部分根據系統的不同會有不同的渲染效果,並在拖拽時跟隨著滑鼠指標。然而,這只是預設拖拽行為的效果,此時沒有監聽程式調整拖拽資料。

在 HTML 中,除了影象、連結和選擇的文字預設的可拖拽行為之外,其他元素在預設情況下是不可拖拽的。

要使其他的 HTML 元素可拖拽,必須做三件事:

  • 將想要拖拽的元素的 draggable 屬性設定成 draggable="true"。
  • 為 [dragstart]事件新增一個監聽程式。
  • 在上一步定義的監聽程式中 設定拖拽資料。

屬性 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()

刪除與給定型別關聯的資料。型別引數是可選的。如果型別為空或未指定,則刪除與所有型別關聯的資料。如果指定型別的資料不存在,或者 data transfer 中不包含任何資料,則該方法不會產生任何效果。

getData()

檢索給定型別的資料,如果該型別的資料不存在或 data transfer 不包含資料,則返回空字串。

setData()

設定給定型別的資料。如果該型別的資料不存在,則將其新增到末尾,以便型別列表中的最後一項將是新的格式。如果該型別的資料已經存在,則在相同位置替換現有資料。

setDragImage()

用於設定自定義的拖動影象。

四、DataTransferItem

DataTransferItem 描述了一個拖拽項。在一個拖拽操作*中,*每一個 drag event 都有一個dataTransfer 屬性,它包含一個存有拖拽資料的 list ,其中每一項都是一個 DataTransferItem 。

4.1 屬性

kind

拖拽項的種類,string 或是 file。

type

拖拽項的型別,一般是一個 MIME 型別。

4.2 方法

getAsFile()

返回一個關聯拖拽項的 File 物件(當拖拽項不是一個檔案時返回 null)。

getAsString()

使用拖拽項的字串作為引數執行指定回撥函數。

webkitGetAsEntry()

返回一個基於 FileSystemEntry 的物件來表示檔案系統中選中的專案。通常是返回一個FileSystemFileEntry 或是 FileSystemDirectoryEntry 物件。

五、DataTransferItemList

5.1 屬性

length

無符號長整型 :列表中拖動項的數量。

5.2 方法

add()

向拖動項列表中新增新項 (File物件或string),該方法返回一個 DataTransferItem 物件。

remove()

根據索引刪除拖動項列表中的物件。

clear()

清空拖動項列表。

DataTransferItem()

取值方法:返回給定下標的DataTransferItem物件。

六、Event事件

drag

在使用者拖動元素或選擇的文字時,每隔幾百毫秒就會被觸發一次。

dragend

在拖放操作結束時觸發(通過釋放滑鼠按鈕或單擊 escape 鍵)。

dragenter

在可拖動的元素或者被選擇的文字進入一個有效的放置目標時觸發。目標物件是使用者直接選擇的範圍(由使用者直接指示作為放置目標的元素),或者 <body> 元素。

dragleave

在拖動的元素或選中的文字離開一個有效的放置目標時被觸發。

dragover

在可拖動的元素或者被選擇的文字被拖進一個有效的放置目標時(每幾百毫秒)觸發。該事件在放置目標上觸發。

dragstart

在使用者開始拖動元素或被選擇的文字時呼叫。

drop

在元素或選中的文字被放置在有效的放置目標上時被觸發。

七、範例

在通過上述的瞭解,咱們已經知道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事件想要被觸發,必須繫結dragover事件,並在dragover事件中執行e.preventDefault()。未繫結dragover事件,則drop事件將不會被觸發。

在第三節,已講解了dataTransfer屬性和方法,我們可能通過它進行資料的傳遞。如dragstartEvent()函數中將被拖拽元素的索引,通過setData儲存到起來,在dragdropEvent()事件執行後,再通過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);
            },
            /**
             * 元素經過某元素位置時,執行事件
             */
            dragoverEvent(e, i){
                e.preventDefault();
            },
            /**
             * 放開元素時執行
             */
            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元素拖放互換內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com