您好,登錄后才能下訂單哦!
HTML 的拖放 API 依賴 DOM 事件模型,獲取拖放和放置元素的相關信息,以此實現拖放功能。我們只需要注冊很少幾個事件監聽器,就能把任何元素變成可拖動或可放置的。
拖放 API 除了提供基本的拖放功能接口外,還可以在拖放之外提供選擇,用來自定義行為。比如,可以修改拖放元素的 CSS 樣式。或者,我們不移動元素,拖動的時候,復制一個副本,拖放結束后,我們就會多了一個同樣的元素。
本篇只介紹實現基本的拖放功能。
將元素設置成可拖動的
我們先從拖動元素開始。假設我們有一個容器元素,其中包含兩種類型的子元素:可拖動元素和可放置元素。舉個例子,如果我們有一個待辦事項列表,我們可以將待辦事項拖到“完成”區域。
簡單起見,我們將移動的元素稱為拖動元素,將拖動元素移入的目標元素稱為 dropzone。
<div class='parent'> <span id='draggableSpan'> draggable </span> <span> dropzone </span> </div>
這是我們的第一段代碼,子元素現在還 不能 拖動。
下面給拖動元素添加屬性 draggable='true'
,將它設置成一個可拖動元素。
<div class='parent'> <span id='draggableSpan' draggable='true'> draggable </span> <span> dropzone </span> </div>
現在你再用鼠標拖動拖動元素的時候,它就會跟隨鼠標移動(對不起,移動端不行:see_no_evil:)。
draggable
屬性在沒設置的情況下,默認值 auto
。就是說,元素是可不可以拖動,取決于瀏覽器的默認設置。比如,鏈接( <a>
)默認就是可拖動的,而 <span>
就不是。
拖放事件處理器
到目前為止,如果我們拖動元素,釋放鼠標,什么事都不會發生。拖動和放置都會觸發事件,實現一個基本的拖放功能,我們最少需要用到拖放 API 中的三個事件:
ondragstart
ondragover
ondrop
學會使用 ondragstart
、 ondragover
、 ondrop
事件只是個開始。拖拽過程一共會涉及八個事件: ondrag
、 ondragend
、 ondragenter
、 ondragexit
、 ondragleave
、 ondragover
、 ondragstart
和 ondrop
。
DataTransfer
DataTransfer
接口中保存了與當前拖放過程相關的跟蹤信息,信息從 DataTransfer
對象屬性中獲得,而 DataTransfer
對象又是從 DOM 事件對象中獲得的。
技術上講, DataTransfer
接口可以同時跟蹤多個拖動對象的信息,我們這里只關注拖動一個元素的情況。:sparkles:
拖動時更新元素
下一步,我們開始設置 ondragstart
的事件處理器。
拖動開始時,我們可以在 ondragstart
處理器中,做任何想做的修改。比如更新拖動元素的 CSS 樣式,將拖動的版本設置為臨時圖片,或者其他能從 DOM 事件中訪問到的任何內容。
dataTransfer
對象的 setData
屬性可以用來設置拖動狀態信息。它接收兩個參數,第一個參數是表示內容格式的字符串,第二個參數是實際傳遞的數據。
我們要實現的功能是將拖動元素移動到一個新的父元素里面。我們需要獲取拖動元素,因此需要將拖動元素的 ID 通過 setData
屬性保存下來:
function onDragStart(event) { event .dataTransfer .setData('text/plain', event.target.id); }
再從事件對象中獲得拖動元素并設置 CSS 樣式:
function onDragStart(event) { event .dataTransfer .setData('text/plain', event.target.id); event .currentTarget .style .backgroundColor = 'yellow'; }
注意:如果上面的黃色背景樣式,你只希望在拖動時才應用,那么拖動結束后,就要手動將樣式恢復。就會說,拖動開始時,如果修改了元素樣式,除非再次修改過來,否則樣式是不會自動恢復的。:rainbow:
拖動開始時的處理函數寫好了,現在將它設置給可拖動元素的 ondragstart
屬性:
<div class='parent'> <span id='draggableSpan' draggable='true' ondragstart='onDragStart(event);'> draggable </span> <span> dropzone </span> </div>
下面是使用鼠標拖動時的效果:
現在拖動元素, ondragstart
中的代碼就會執行,樣式改變了,但釋放拖動元素后,什么事情都沒發生。接下來我們將視線轉移到 dropzone 上來。
設置元素為可放置的
ondragstart
之后,下一個要寫的處理函數就是 ondragover
了。上面講過,放置行為默認是被瀏覽器阻止的,我們需要取消這個默認行為,雙重否定為肯定,對吧?
function onDragOver(event) { event.preventDefault(); }
在阻止瀏覽器干擾后,現在就能將拖動元素添加到 dropzone 了,dropzone 成為能夠接受任何拖動元素的容器元素。
<div class='parent'> <span id='draggableSpan' draggable='true' ondragstart='onDragStart(event);'> draggable </span> <span ondragover='onDragOver(event);'> dropzone </span> </div>
即便現在 dropzone 可以接受拖動元素,釋放鼠標后還是看不見改變發生。
放置的時候要做什么?
現在要介紹第三個也是最后一個處理函數 ondrop
。
我們的函數邏輯遵循以下步驟:
setData
中設置的數據嗎?dataTransfer
對象的 getData
屬性中獲取設置的數據,數據內容是拖動元素的 ID,它會返回給我們。function onDrop(event) { const id = event .dataTransfer .getData('text'); const draggableElement = document.getElementById(id); const dropzone = event.target; dropzone.appendChild(draggableElement); event .dataTransfer .clearData(); }
因為這是我們要寫的第三個也是最后一個函數,我們只要將它傳遞給 dropzone 的 ondrop
屬性,就完成了一個完整的拖放功能!
<div class='parent'> <span id='draggableSpan' draggable='true' ondragstart='onDragStart(event);'> draggable </span> <span ondragover='onDragOver(event);' ondrop='onDrop(event);'> dropzone </span> </div>
這里寫的示例是最基本的,它展示如何使頁面上的任何內容可變得可拖動。當然,一個網頁里可以同時包含多個可拖動元素、多個 dropzone,或者使用文本沒有介紹的其他事件做更加細粒度的自定義設置。
下面展示的是本文一開始提到的那個簡單的待辦事項列表功能。:fire:
只要依據本文上面已經講過的內容,稍微變通一下,就能寫出來。只要確保這里可拖動待辦項目的 ID 是唯一的就行了。
總結
以上所述是小編給大家介紹的基于JavaScript 實現拖放功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。