拖放事件:
拖動元素時,依次觸發的事件:
- dragstart 按下鼠標並移動時觸發
- drag 拖動期間持續觸發
- dragend 鬆開鼠標觸發
拖動到有效的放置目標上時,依次觸發:
- dragenter 元素被拖到放置目標上
- dragover 被拖元素在放置目標內移動,持續觸發
- dragleave或drop dragleave,元素被拖到放置目標外觸發;drop元素被拖到有效的放置目標上(默認無效),並鬆開鼠標觸發
實現代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>table</title>
<style>
tr,th {
padding: 30px;
}
</style>
</head>
<body>
<table id="myTable" border="1" >
<tbody>
<tr>
<th>序列</th>
<th>名稱</th>
<th>單價</th>
<th>數量</th>
</tr>
<tr draggable="true">
<td>1</td>
<td>冰箱</td>
<td>13</td>
<td>14</td>
</tr>
<tr draggable="true">
<td>2</td>
<td>彩電</td>
<td>113</td>
<td>114</td>
</tr>
<tr draggable="true">
<td>3</td>
<td>空調</td>
<td>12</td>
<td>12</td>
</tr>
<tr draggable="true">
<td>4</td>
<td>洗衣機</td>
<td>12</td>
<td>12</td>
</tr>
</tbody>
</table>
<script>
function drag_row_table() {
var EventUtil = { //跨瀏覽器的事件處理程序,視情況分別選擇以下事件處理程序
addHandler: function(element, type, handler) {
if(element.addEventListener) { //DOM2級
element.addEventListener(type, handler, false);
}
else if (element.attachEvent) { //IE方法
element.attachEvent('on' + type.handler);
}
else { //DOM1級
element["on" + type] = handler;
}
},
preventDefault: function(event) { //取消事件默認方法
if(event.preventDefault) {
event.preventDefault();
}
else {
event.returnValue = false; //默認爲true,設爲falsew爲取消默認行爲。
}
}
}
var myTable = document.querySelector('#myTable');
var tbody = document.querySelector("tbody");
var trs = myTable.querySelectorAll("tr");
for(var i=1; i < trs.length; i++) { //爲每一行註冊監聽事件
EventUtil.addHandler(trs[i], "dragover", function(event) { //默認元素不可放置,這裏取消默認,將放置目標修改爲可放置的
EventUtil.preventDefault(event);
})
EventUtil.addHandler(trs[i], "dragstart", function(event) { //監聽點擊的拖動的元素
event.dataTransfer.setData("drag_index", event.currentTarget.rowIndex); //將被拖元素的信息,傳給放置位置
})
EventUtil.addHandler(trs[i], "drop", function(event) { //監聽鼠標移動到可放置的放置目標上,鬆開鼠標的事件
EventUtil.preventDefault(event); //取消在Firefox 3.5+中,放置事件的默認行爲是打開被放置目標上的URL
let drag_index = parseInt(event.dataTransfer.getData("drag_index")); //獲取傳過來的被拖元素的信息
let drop_index = this.rowIndex; //this爲當前觸發drop的元素,即放置目標的行下標
tbody.insertBefore(trs[drag_index], this.nextSibling); //將被拖元素放到放置目標的兄弟節點上
trs = myTable.querySelectorAll("tr"); //更新變換的tr行信息
})
}
}
drag_row_table();
</script>
</body>
</html>
效果:
這裏遇到的坑是,querySelectorAll()方法的底層實現是類似於一組元素的快照,而不是動態查詢的(即更新文檔結構時,對應的變量也自動更新),爲的是避免使用NodeList對象引起的性能問題。因此我們得手動更新querySelectorAll()方法的變量。
符合動態查詢的方法有getElementsByTagName()