- ベストアンサー
テーブルソート
お世話になります 今テーブルソートをしているのですがIE,Operaではうまくいったのですがfirefoxでは nodeArray[i].childNodes[k].firstChild has no properties と警告が出てソーティングがうまくできません どのようにすればいいでしょうか? p.s. 下記のテーブルはCGIで動的に書いたソースをコピーして擬似表示したものです 状況:偶数のonclickが作動せず奇数のonclickがずれてテーブルソートしています onclick(3)でHPのソート、onclick(5)でMPのソートという感じです・・・ 参考にしたサイトや静的に表示したテーブルでは正常に機能することもあります <script language="javascript"><!-- var x=new Array(); var nodeArray=new Array(); var n; function sortTable(k) { if(!document.getElementById) return; n = document.getElementById("ranksort").rows.length; for(i=0;i<n;i++){ nodeArray[i]=document.getElementById("t["+i+"]"); } for(i=0;i<n;i++){ xval=nodeArray[i].childNodes[k].firstChild.nodeValue; x[i]=parseFloat(xval); } sort(); show(); } function sort(){ complete=false; while(!complete){ complete=true; for(i=0;i<n-1;i++){ if(x[i]<x[i+1]){ buf=x[i];x[i]=x[i+1];x[i+1]=buf; buf=nodeArray[i];nodeArray[i]=nodeArray[i+1];nodeArray[i+1]=buf; complete=false; } } } } function show(){ tbody=document.getElementById('ranksort') for(i=0;i<n;i++){ tbody.removeChild(nodeArray[i]); } for(i=0;i<n;i++){ tbody.appendChild(nodeArray[i]); } } //--> </script> <div id='ability box'> <small>タイトルをクリックするとランキングソートされます</small> <table lang="ja" border="1" style='font-size:14px;'> <thead> <tr> <th>名前</th> <th onclick='sortTable(1);'>H P</th> <th onclick='sortTable(2);'>M P</th> <th onclick='sortTable(3);'>力</th> <th onclick='sortTable(4);'>知能</th> <th onclick='sortTable(5);'>信仰心</th> <th onclick='sortTable(6);'>生命力</th> <th onclick='sortTable(7);'>素早さ</th> <th onclick='sortTable(8);'>運</th> <th onclick='sortTable(9);'>人気</th> <th onclick='sortTable(10);'>賞金額</th> </tr> </thead> <tbody id="ranksort"> <tr id="t[0]"> <td>452</td> <td>32</td> <td>15</td> <td>13</td> <td>5</td> <td>5</td> <td>6</td> <td>5</td> <td>10</td> <td>0</td> <td>10000000</td> </tr> <tr id="t[1]"> <td>コス</td> <td>26</td> <td>14</td> <td>6</td> <td>6</td> <td>13</td> <td>11</td> <td>10</td> <td>13</td> <td>0</td> <td>0</td> </tr> <tr id="t[2]"> <td>コスモス</td> <td>30</td> <td>11</td> <td>13</td> <td>13</td> <td>12</td> <td>6</td> <td>6</td> <td>5</td> <td>0</td> <td>0</td> </tr> </tbody></table> </div>
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
===========Q3160237-1.html (BOM付きUTF-8)==================== <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <title>テスト</title> <!-- XMLとCDATAセクションを意識すると色々複雑なので別ファイルにした --> <script type="text/javascript" src="Q3160237-1.js"></script> </head> <body> <!-- id属性の命名規則の変更についてはjavascriptのソースにも述べているが "["や"]",および空白を含まないようにして、かつ、大文字に変更している --> <div id="ABILITYBOX"> <!-- 多分id属性に空白は取れない。複数の値を取れるclassには入れられるが --> <small>タイトルをクリックするとランキングソートされます</small> <table lang="ja" border="1" style="font-size:14px;"> <thead> <tr> <th>名前</th> <!-- 今は特に述べる気は無いけれど 番号での管理でなく、ハッシュテーブルを使った管理の方が後々楽なこともあるかも--> <th onclick='sortTable(1);'>H P</th> <th onclick='sortTable(2);'>M P</th> <th onclick='sortTable(3);'>力</th> <th onclick='sortTable(4);'>知能</th> <th onclick='sortTable(5);'>信仰心</th> <th onclick='sortTable(6);'>生命力</th> <th onclick='sortTable(7);'>素早さ</th> <th onclick='sortTable(8);'>運</th> <th onclick='sortTable(9);'>人気</th> <th onclick='sortTable(10);'>賞金額</th> </tr> </thead> <tbody id="RANKSORT"> <tr id="T0"> <td>452</td> <td>32</td> <td>15</td> <td>13</td> <td>5</td> <td>5</td> <td>6</td> <td>5</td> <td>10</td> <td>0</td> <td>10000000</td> </tr> <tr id="T1"> <td>コス</td> <td>26</td> <td>14</td> <td>6</td> <td>6</td> <td>13</td> <td>11</td> <td>10</td> <td>13</td> <td>0</td> <td>0</td> </tr> <tr id="T2"> <td>コスモス</td> <td>30</td> <td>11</td> <td>13</td> <td>13</td> <td>12</td> <td>6</td> <td>6</td> <td>5</td> <td>0</td> <td>0</td> </tr> </tbody> </table> </div> </body> </html> ===========Q3160237-1.js (BOM付きUTF-8)==================== /* Option Explicit(変数宣言の強制)だと思っておこう。*/ var x=new Array(); var nodeArray = new Array(); var n; var MODE = "HTML"; function sortTable(k) { if(!document.getElementById){ return; } /* id属性大文字 */ /* HTML,XHTML的にはOKなんだけど、XML的に見ると少し気になる(汗) */ n = document.getElementById("RANKSORT").rows.length; for(var i=0;i<n;i++){ /* id属性として"["や"]"が使えるとは思わない。ので修正しよう! 厳密には、HTMLではid属性は大文字になるので念のために変更しておく */ nodeArray[i]=document.getElementById("T"+i); } for(var i=0;i<n;i++){ var xval; /* 【改行文字はテキストノード】でchildNodesに含まれるから気をつけよう firstChildにしているのはIEとそれ以外のブラウザでinnerTextとtextContentを使い分けたくないからだ。 */ if(MODE == "XML"){ xval = nodeArray[i].getElementsByTagNameNS("http://www.w3.org/1999/xhtml","td")[k].firstChild.nodeValue; x[i]=parseFloat(xval); } else if(MODE == "HTML"){ xval = nodeArray[i].getElementsByTagName("td")[k].firstChild.nodeValue; x[i]=parseFloat(xval); } } sort(); show(); } function sort(){ var complete; complete=false; while(!complete){ complete=true; for(var i=0;i<n-1;i++){ if(x[i]<x[i+1]){ var buf; buf=x[i];x[i]=x[i+1];x[i+1]=buf; buf=nodeArray[i];nodeArray[i]=nodeArray[i+1];nodeArray[i+1]=buf; complete=false; } } } } function show(){ var tbody; /* この辺は面白かった */ tbody=document.getElementById("RANKSORT"); /* id属性大文字 */ for(var i=0;i<n;i++){ tbody.removeChild(nodeArray[i]); } for(var i=0;i<n;i++){ tbody.appendChild(nodeArray[i]); } }
その他の回答 (3)
- steel_gray
- ベストアンサー率66% (1052/1578)
原因に関しては他の方の回答で。 onclickで数値を書いて渡すとか、自前でsortするところとかちょっと改善。 今回はCGIで吐き出すHTMLという事でそのままにしましたが セルの値を得るあたりは他の方もいっていますが、改行が別ノードととられる場合があるので注意が必要。 <html> <head> <title></title> <style type="text/css"> </style> <script type="text/javascript"> function sortTable(Cell) { var TB = Cell.parentNode.parentNode.parentNode.tBodies[0]; var workT = new Array; while(TB.rows.length) { var wO = new Object(); wO.rec = TB.rows[0].cloneNode(true);; wO.value = parseInt(TB.rows[0].cells[Cell.cellIndex].firstChild.nodeValue); TB.deleteRow(0); workT.push(wO); } workT.sort(rankCmp); while(workT.length) { TB.appendChild(workT[0].rec); workT.shift(); } } function rankCmp(a,b) { if(b.value < a.value) return 1; if(b.value > a.value) return -1; return 0; } </script> </head> <body> <div id='ability box'> <small>タイトルをクリックするとランキングソートされます</small> <table lang="ja" border="1" style='font-size:14px;'> <thead> <tr> <th>名前</th> <th onclick='sortTable(this);'>H P</th> <th onclick='sortTable(this);'>M P</th> <th onclick='sortTable(this);'>力</th> <th onclick='sortTable(this);'>知能</th> <th onclick='sortTable(this);'>信仰心</th> <th onclick='sortTable(this);'>生命力</th> <th onclick='sortTable(this);'>素早さ</th> <th onclick='sortTable(this);'>運</th> <th onclick='sortTable(this);'>人気</th> <th onclick='sortTable(this);'>賞金額</th> </tr> </thead> <tbody id="ranksort"> <tr> <td>452</td> <td>32</td> <td>15</td> <td>13</td> <td>5</td> <td>5</td> <td>6</td> <td>5</td> <td>10</td> <td>0</td> <td>10000000</td> </tr> <tr> <td>コス</td> <td>26</td> <td>14</td> <td>6</td> <td>6</td> <td>13</td> <td>11</td> <td>10</td> <td>13</td> <td>0</td> <td>0</td> </tr> <tr> <td>コスモス</td> <td>30</td> <td>11</td> <td>13</td> <td>13</td> <td>12</td> <td>6</td> <td>6</td> <td>5</td> <td>0</td> <td>0</td> </tr> </tbody></table> </div> </body> </html>
お礼
回答ありがとうございます TB.deleteRow(0); とか workT.push(wO); とか workT.shift(); など見た事ない処理でとても新鮮でした(^^) あとソートが降順でなく昇順になっておられたようなのでrankCmp(a,b)の > < を反対にして使わせてもらいます ありがとうございます
nodeArray[0](document.getElementById(t[0])) の childNodes[0] が nodeName=#text(改行) なら テキストノードにfirstChildプロパティは無いからだと思います。 それかfirstChildがundefinedでそのnodeValueを参照しようとしているためundefinedにnodeValueプロパティが無いせいかもしれません IE6はtrの開始タグ直後の改行はchildNodesにならないと思いました。 try{ xval=nodeArray[i].childNodes[k].firstChild.nodeValue; }catch(e){ ?????? } if(typeof nodeArray[i].childNodes[k] == "object"){ xval=nodeArray[i].childNodes[k].firstChild.nodeValue; }else if(typeof nodeArray[i].childNodes[k] == "string"){ ????? }
お礼
回答ありがとうございます No.1様のお礼にも書きましたがDOM初心者です(--;) try { } は何処に差し込めばよかったのでしょうか? ?????の部分は何でしょう? 詳しく回答していただいたのにこちらの知識不足ですみません
>nodeArray[i].childNodes[k].firstChild nodeArray[i].childNodes[0] ←→ nodeArray[i].childNodes.firstChild だからじゃない?
お礼
回答ありがとうございます すみません。質問内に追記しておけばよかったですね(--;) サンプルソースもnの値を取得するところとid名を変えただけのDOM初心者です(><) ですのでこれをどのように使えばよいのか分かりませんでした・・・ せっかく回答していただいたのにすみません
お礼
回答ありがとうございます 教示ソースをコピペして試したところ xval = nodeArray[i].getElementsByTagNameNS("http://www.w3.org/1999/xhtml","td")[k].firstChild.no... の部分でsyntax errorとなりましたが 最後のno...をnodeValue;にかえたところうまくいきました(^^) ありがとうございます