一、簡介
- 在Web開發中,用戶與內容的交互方式直接影響用戶體驗的深度。
- 在 HTML 中,
draggable
是一個全局屬性,通過簡單配置即可讓任意元素實現拖拽功能。- 也可通過結合
draggable
屬性和 JavaScript 事件,可以實現豐富的拖放交互功能。- 為構建可視化編輯器、任務看板、工作流拖拽等場景提供了原生支持。
- 本文將系統解析該屬性的使用方法、事件機制及 dataTransfer 實現跨元素數據交互等要點。
二、基本語法
draggable
它是一個布爾屬性,可以設置為true
或false
,默認值為false
(除非元素是默認可拖動的,如<img>
或<a>
標簽)。
<element draggable="true|false|auto">
屬性值與作用范圍
draggable
作為全局布爾屬性,支持三種取值:
true
:強制啟用拖拽(如<div draggable="true">
)false
:禁用拖拽(覆蓋默認行為)auto
(默認):遵循瀏覽器規則(鏈接/圖片默認可拖拽)
特殊說明:
- 表單控件(
<input>
/<button>
)和表格結構元素(<th>
/<td>
)默認不支持拖拽 - 文本選中狀態下拖拽會觸發系統默認的文本復制行為
- 移動端需配合觸摸事件或第三方庫(如interact.js)實現兼容
eg:示例代碼
1.使 <div>
可拖動
<div draggable="true" style="width: 100px; height: 100px; background: lightblue;">拖動我!
</div>
- 禁止圖片拖動(覆蓋默認行為)
<img src="example.jpg" draggable="false" alt="不可拖動的圖片">
三、拖拽事件生命周期
要實現完整的拖放功能,需要結合 JavaScript 監聽拖放相關事件:
完整的拖拽操作涉及7個關鍵事件,按觸發順序如下:
事件類型 | 觸發場景 | 典型用途 |
---|---|---|
dragstart | 用戶開始拖拽元素時 | 設置拖拽數據、預覽樣式 |
drag | 拖拽過程中持續觸發(每350ms) | 實時反饋位置(需節流處理) |
dragend | 拖拽結束時(無論成功/取消) | 清理臨時狀態 |
dragenter | 拖拽元素進入放置區域時 | 高亮顯示放置區域 |
dragover | 拖拽元素在放置區域內移動時 | 必須調用preventDefault() |
dragleave | 拖拽元素離開放置區域時 | 恢復放置區域樣式 |
drop | 元素在放置區域釋放時 | 處理業務邏輯 |
四、數據傳遞
通過 dataTransfer 對象在拖放事件中傳遞數據
dataTransfer
對象是 HTML5 拖放 API 的核心部分。- 它允許在拖放操作期間在不同元素之間傳遞數據。
- 通過
setData()
方法設置數據,通過getData()
方法獲取數據 - 實現步驟
- 在
dragstart
事件中,使用setData()
設置要傳遞的數據- 在
drop
事件中,使用getData()
獲取之前設置的數據
eg:示例代碼
<!DOCTYPE html>
<html><head><title>拖放數據傳遞示例</title><style>#dragItem {width: 100px;height: 50px;background-color: #3498db;color: white;text-align: center;line-height: 50px;cursor: move;margin: 20px;}#dropZone {width: 300px;height: 200px;border: 2px dashed #7f8c8d;background-color: #ecf0f1;text-align: center;line-height: 200px;margin: 20px;}</style>
</head><body><div id="dragItem" draggable="true">拖我</div><div id="dropZone">放到這里</div><script>const dragItem = document.getElementById('dragItem');const dropZone = document.getElementById('dropZone');/*** dragItem 元素處理拖動開始事件* 1. 設置數據,第一個參數是數據格式,第二個參數是數據內容*/dragItem.addEventListener('dragstart', function (e) {console.log('開始拖動,設置數據');// 設置數據,第一個參數是數據格式,第二個參數是數據內容e.dataTransfer.setData('text/plain', '這是通過dataTransfer傳遞的消息');e.dataTransfer.setData('application/json', JSON.stringify({ id: 1, name: '示例對象' }));});/*** dropZone 元素處理拖拽經過放置區事件* 1. 阻止默認行為以允許放置*/dropZone.addEventListener('dragover', function (e) {e.preventDefault();});/*** dropZone 元素處理放置事件 * 1. 阻止默認行為以允許放置* 2. 獲取之前設置的數據* 3. 顯示接收到的數據* 4. 改變背景色以示反饋*/dropZone.addEventListener('drop', function (e) {e.preventDefault();// 獲取之前設置的數據,第一個參數是數據格式,第二個參數是數據內容const textData = e.dataTransfer.getData('text/plain');const jsonData = e.dataTransfer.getData('application/json');console.log('獲取到的文本數據:', textData);console.log('獲取到的JSON數據:', JSON.parse(jsonData));dropZone.textContent = `已接收數據: ${textData}`;dropZone.style.backgroundColor = '#2ecc71';});</script>
</body></html>
五、注意事項
- 默認可拖動元素:如
<img>
、<a>
(帶href
)默認支持拖動,無需設置draggable="true"
。 - 移動端兼容性:部分移動設備對拖放支持有限,需測試目標平臺。
- 數據傳遞:通過
dataTransfer
對象在拖放事件中傳遞數據(如示例中的setData
/getData
)