テーブルの行をマウスで入れ替える。WAI-ARIAは、後回し・ええぇ、腰が痛いから。

簡単にできるだろうと思ったら、tbody が複数ある場合の対処に苦戦。

<!DOCTYPE html>
<title></title>
<meta charset="UTF-8">

<style type="text/css">
table, th, td {
  border :1px #00f solid;
}
thead {
  background-color:#faa;
}
tfoot {
  background-color:#aaf;
}
tbody:nth-of-type(1) {
  background-color:#fdd;
}
tbody:nth-of-type(2) {
  background-color:#ddf;
}

</style>

<table>
  <thead>
    <tr><th>No <th>Name     <th>TEL
  </thead>
  
  <tfoot>
    <tr><th>No <th>Name     <th>TEL
  </tfoot>
  
  <tbody>
    <tr><td>1  <td>Satou    <td>11-1111
    <tr><td>2  <td>Suzuki   <td>22-2222
    <tr><td>3  <td>Takahasi <td>33-3333
    <tr><td>4  <td>Tanaka   <td>44-4444
    <tr><td>5  <td>Watanabe <td>55-5555
  </tbody>
  <tbody>
    <tr><td>6  <td>Itou     <td>66-6666
    <tr><td>7  <td>Yamamoto <td>77-7777
    <tr><td>8  <td>Nakamura <td>88-8888
    <tr><td>9  <td>Kobayashi<td>99-9999
    <tr><td>10  <td>Kato    <td>00-0000
  </tbody>
</table>

<script type="application/javascript; version=1.8">

(function () {
  var stock = []; // テーブル要素を保存
  
  function Dragger (table) {
    this.table = table;
    this.row = null;
  }
  
  
  function getParent (a, b, c) {
    return a ? c == a[b] ? a : arguments.callee (a.parentNode, b, c): null;
  }
  
  
  function onMouseUp (event) {
    this.row = null;
    this.table.style.cursor = 'auto';
  }
  
  
  function onMouseDown (event) {
    var tr = getParent (event.target, 'nodeName', 'TR');
    var tbody = getParent (tr, 'nodeName', 'TBODY');
    
    if (tbody) {
      this.table.style.cursor = 'move';
      this.row = tr;
    }
  }
  
  
  function onMouseMove (event) {
    if (! this.row)
      return;
    
    var tr = getParent (event.target, 'nodeName', 'TR');
    var tbody = getParent (tr, 'nodeName', 'TBODY');
    
    if ((! tbody) || (this.row == tr))
      return;

    if (this.row.rowIndex < tr.rowIndex) {
      tr.parentNode.insertBefore (this.row, tr);
      tr.parentNode.insertBefore (tr, this.row);
    }
    else
      tr.parentNode.insertBefore (this.row, tr);

    tr.ownerDocument.defaultView.getSelection ().removeAllRanges ();
  }

  
  function handler (event) {
    switch (event.type) {
    
      case 'mousedown' :
        onMouseDown.call (this, event);
        break;
        
      case 'mouseup' :
        onMouseUp.call (this, event);
        break;
      
      case 'mousemove' :
        onMouseMove.call (this, event);
        break;
    }
  }
  
  
  function setEvent () {
    this.table.addEventListener ('mousedown', this, false);
    this.table.addEventListener ('mousemove', this, false);
    this.table.addEventListener ('mouseup', this, false);
  }
  
  
  function create (table) {
    if ('TABLE' !== table.nodeName)
      return null;
    
    if (-1 < stock.indexOf (table))
      return null;
    
    var obj = new Dragger (table);
    obj.setEvent ();
    
    stock.push (table)
  }
  
  //____________
  
  Dragger.prototype.setEvent = setEvent;
  Dragger.prototype.handleEvent = handler;
  Dragger.create = create;

  this.TableDragger = Dragger;
})();

TableDragger.create (document.querySelector ('table'));
</script>

花火大会、アイディアはあるんだ。中国のオリンピックの開幕のCGでやったデカ足跡の花火。ただ暇と技量が無い!