tableのtr要素をドラッグ&ドロップで任意に入れ替え
http://oshiete.goo.ne.jp/qa/6275238.html
yyr446 さんの回答(無許可です^^;)を、自分流にインデント処理しながらちょこちょこと。
勉強させて頂きます。(明日から忙しいぞ!)
<!DOCTYPE html> <title></title> <style type="text/css"> table, th { border:1px #c88 outset; } td { border:1px #c88 inset; } </style> <body> <table id="dragtable"> <tbody> <tr><th>A</th><th>B</th><th>C</th></tr> <tr draggable="true"><td>a</td><td>b</td><td>c</td></tr> <tr draggable="true"><td>あ</td><td>い</td><td>う</td></tr> <tr draggable="true"><td rowspan="2">1</td><td>2</td><td>3</td></tr> <tr draggable="true"><td>ろ</td><td>は</td></tr> <tr draggable="true"><td>x</td><td>y</td><td>z</td></tr> <tr draggable="true"><td>X</td><td>Y</td><td>Z</td></tr> </tbody> </table> <script type="text/javascript"> var bind = function (func, that) { return function () { func.apply (that, arguments); }; }; function Dragtable (table) { var canvas = document.createElement ('canvas'); var ctx = canvas.getContext ('2d'); table.addEventListener ('dragstart', bind (this.handleEvent, this), false); table.addEventListener ('dragover', bind (this.handleEvent, this), false); table.addEventListener ('drop', bind (this.handleEvent, this), false); table.addEventListener ('dragend', bind (this.handleEvent, this), false); canvas.width = canvas.height = 26; ctx.lineWidth = 2; ctx.moveTo (0, 0), ctx.lineTo (26, 13), ctx.moveTo (0, 26), ctx.lineTo (26, 13); ctx.stroke (); this.table = table; this.canvas = canvas; this.rowspan = 0; } Dragtable.prototype.handleEvent = function (event) { var dt = event.dataTransfer; var target = event.target; var trs; var tr; var i; var target_tr; var idx; var target_table; switch (event.type) { case 'dragstart': trs = target.innerHTML; this.rowspan = 0; this.rowspanchk (target); if (this.rowspan > 0) for (i = 0; i < this.rowspan - 1; i++) trs += '~' + target.nextElementSibling.innerHTML; dt.setData ('text/plain', trs); dt.setDragImage (this.canvas, 13, 13); dt.effectAllowed = 'move'; return; case 'dragover': if (target.nodeName == 'TD' || target.nodeName == 'TH') event.preventDefault (); return; case 'drop': trs = dt.getData ('text/plain').split ('~'); target_tr = target.parentNode; for (i = trs.length; i > 0; i--) { tr = target_tr.parentNode.insertRow (target_tr.rowIndex); tr.innerHTML = trs[i - 1]; tr.setAttribute ('draggable', 'true'); target_tr.parentNode.insertBefore (tr, target_tr.nextElementSibling); } event.preventDefault (); return; case 'dragend': if (dt.dropEffect == 'move') target_table = target.parentNode; idx = target.rowIndex; if (this.rowspan == 0) target_table.deleteRow (idx); else for (i = this.rowspan - 1; i >= 0; i--) target_table.deleteRow (idx + i); return; } } Dragtable.prototype.rowspanchk = function (tr) { var td = tr.childNodes; var rowspan = []; for (var i = 0; i < td.length; i++) { if (td[i].getAttribute ('rowspan') > 0) rowspan.push (td[i].getAttribute ('rowspan')); } rowspan.sort (); if (rowspan[0]) { this.rowspan += rowspan[0]; arguments.callee (tr.nextElementSibling); } }; myDragTable = new Dragtable (document.getElementById ('dragtable')); </script>