1、拖放(Drag 和 drop)是 HTML5 標准的組成部分。
拖放是一種常見的特性,即抓取對象以后拖到另一個位置。在 HTML5 中,拖放是標准的一部分,任何元素都能夠拖放。
瀏覽器支持:Internet Explorer 9、Firefox、Opera 12、Chrome 以及 Safari 5 支持拖放(注:在 Safari 5.1.2 中不支持拖放。)。
2、相關屬性及方法
設置元素為可拖放,把 draggable 屬性設置為 true
<labeldraggable="true"">index1</label>
設置元素被拖動時觸發的事件 ondragstart
<label draggable="true" ondragstart="drag(event)">...</label>
放到何處 - ondragover ,以div 為例:
<div id="right" ondragover="dragover(event)">...</div>
進行放置 - ondrop,以div 為例:
<div id="right" ondragover="dragover(event)" ondrop="drop(event)">...</div>
3、實現一個簡單的 從左向右 或 從右向左 拖動元素,且可以移動元素之前的排列位置。
效果圖:
圖1.初次加載
圖2.從左向右拖動元素
圖3.打亂右側元素排序
圖4.把右側元素移向左邊
html:
拖動元素的方法,未在元素上進行綁定,均在 js 里進行綁定
1 <h2>拖放(Drag 和 drop)</h2> 2 <!-- 左邊元素框 --> 3 <div id="left"> 4 <label draggable="true">index1</label> 5 <label draggable="true">index2</label> 6 <label draggable="true">index3</label> 7 <label draggable="true">index4</label> 8 <label draggable="true">index5</label> 9 <label draggable="true">index6</label> 10 <label draggable="true">index7</label> 11 </div> 12 <!-- 右邊元素框 --> 13 <div id="right"></div>
javascript:
動態給 label元素 加上 id屬性 及拖動事件
1 var moveItem = document.getElementsByTagName('label'); 2 3 for (let i = 0; i < moveItem.length; i++) { 4 //動態設置label元素id 5 moveItem[i].setAttribute('id', 'label' + i); 6 moveItem[i].ondragstart = function (ev) { 7 //dataTransfer.setData() 方法設置被拖數據的數據類型和值 8 ev.dataTransfer.setData("Text", this.id); 9 }; 10 }
設置 左邊-〉右邊 拖動 或 自身元素排序
1 document.getElementById('right').ondragover = function (ev) { 2 ev.preventDefault(); //阻止向上冒泡 3 } 4 document.getElementById('right').ondrop = function (ev) { 5 ev.preventDefault(); 6 var id = ev.dataTransfer.getData('Text'); 7 var elem = document.getElementById(id); //當前拖動的元素 8 var toElem = ev.toElement.id; //放置位置 9 if (toElem == 'right') { 10 //如果為container,元素放置在末尾 11 this.appendChild(elem); 12 } else { 13 //如果為container里的元素,則插入該元素之前 14 this.insertBefore(elem, document.getElementById(toElem)); 15 } 16 }
設置右邊-〉左邊拖動 或 自身元素排序
1 document.getElementById('left').ondragover = function (ev) { 2 ev.preventDefault(); //阻止向上冒泡 3 } 4 document.getElementById('left').ondrop = function (ev) { 5 ev.preventDefault(); 6 var id = ev.dataTransfer.getData('Text'); 7 var elem = document.getElementById(id); 8 var toElem = ev.toElement.id; 9 if (toElem == 'left') { 10 //如果為container,元素放置在末尾 11 this.appendChild(elem); 12 } else { 13 //如果為container里的元素,則插入該元素之前 14 this.insertBefore(elem, document.getElementById(toElem)); 15 } 16 }
代碼解釋:
- ondragover 默認地,無法將數據/元素放置到其他元素中。如果需要設置允許放置,我們必須阻止對元素的默認處理方式。
- 調用 preventDefault() 來避免瀏覽器對數據的默認處理(drop 事件的默認行為是以鏈接形式打開)
- 通過 dataTransfer.getData("Text") 方法獲得被拖的數據。該方法將返回在 setData() 方法中設置為相同類型的任何數據。
完整代碼

<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>拖動</title> <style> h2 { font-size: 20px; color: #0d88c1; } div#left, div#right { width: 120px; float: left; margin: 10px 100px 10px 0px; height: 240px; background-color: #dddddd; border: 1px solid #000; overflow-y: auto; } div label { font-size: 22px; font-weight: bold; width: 100%; display: inline-block; padding: 4px 0; text-align: center; margin: 0px 0 2px 0; color: #fff; background-color: #0d88c1; } </style> </head> <body> <h2>拖放(Drag 和 drop)</h2> <!-- 左邊元素框 --> <div id="left"> <label draggable="true">index1</label> <label draggable="true">index2</label> <label draggable="true">index3</label> <label draggable="true">index4</label> <label draggable="true">index5</label> <label draggable="true">index6</label> <label draggable="true">index7</label> </div> <!-- 右邊元素框 --> <div id="right"></div> <script> var moveItem = document.getElementsByTagName('label'); for (let i = 0; i < moveItem.length; i++) { //動態設置label元素id moveItem[i].setAttribute('id', 'label' + i); moveItem[i].ondragstart = function (ev) { //dataTransfer.setData() 方法設置被拖數據的數據類型和值 ev.dataTransfer.setData("Text", this.id); }; } //左-〉右 document.getElementById('right').ondragover = function (ev) { ev.preventDefault(); //阻止向上冒泡 } document.getElementById('right').ondrop = function (ev) { ev.preventDefault(); var id = ev.dataTransfer.getData('Text'); var elem = document.getElementById(id); //當前拖動的元素 var toElem = ev.toElement.id; //放置位置 if (toElem == 'right') { //如果為container,元素放置在末尾 this.appendChild(elem); } else { //如果為container里的元素,則插入該元素之前 this.insertBefore(elem, document.getElementById(toElem)); } } //右-〉左 document.getElementById('left').ondragover = function (ev) { ev.preventDefault(); //阻止向上冒泡 } document.getElementById('left').ondrop = function (ev) { ev.preventDefault(); var id = ev.dataTransfer.getData('Text'); var elem = document.getElementById(id); var toElem = ev.toElement.id; if (toElem == 'left') { //如果為container,元素放置在末尾 this.appendChild(elem); } else { //如果為container里的元素,則插入該元素之前 this.insertBefore(elem, document.getElementById(toElem)); } } </script> </body> </html>