人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

javascriptの質問です
selectで回数の範囲を選び、その選んだ行をシャッフルして表示するというプログラムを作りたいと思っています。
どうすればjavascriptで回数を回数を選んで表示できるでしょうか?

<html><head><script>
function sortTable(){
var tabs = document.getElementsByTagName('TABLE');
var tab = tabs[0];
var bodies = Array.prototype.slice.apply(tab.getElementsByTagName('tr'));
for (var r = bodies.length; r > 0; r--) {
var index = Math.floor(r * Math.random());tab.appendChild(bodies[index]);
bodies.splice(index, 1);}}</script></head>
<body>回数範囲選択
<select name="kaisu1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>?
<select name="kaisu2">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<input type="button" value="をシャッフル表示" onclick="sortTable()">
<table>
<tr><td>回数</td><td></td></tr>
<tr><td>1</td><td>a</td></tr>
<tr><td>2</td><td>b</td></tr>
<tr><td>3</td><td>c</td></tr>
<tr><td>4</td><td>d</td></tr>
</table></body></html>

よろしくお願いします。

●質問者: takanii
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● Lhankor_Mhy
●51ポイント

もともとのコードからは大分変わってしまいますが。

function sortTable(){
 var kaisu1 = document.getElementsByName('kaisu1')[0].value;
 var kaisu2 = document.getElementsByName('kaisu2')[0].value;
 var kaisuLength = Math.abs(kaisu1 - kaisu2)+1;
 var kaisuMin = Math.min(kaisu1, kaisu2);
 var tabs = document.getElementsByTagName('TABLE');
 var tab = tabs[0];
 var bodies = Array.prototype.slice.apply(tab.getElementsByTagName('tr'));
 var keyArr = new Array(bodies.length);
 
 for (var i = 0; i < keyArr.length; i++) keyArr[i] = i;
 for (var i = 0; i < 100; i++) {
 var swap1 = Math.floor(kaisuLength * Math.random() + kaisuMin);
 var swap2 = Math.floor(kaisuLength * Math.random() + kaisuMin);
 keyArr[swap1] = [keyArr[swap2], keyArr[swap2] = keyArr[swap1]][0];
 }
 for (var i = 0; i < bodies.length; i++) tab.appendChild(bodies[keyArr[i]]);
}

a-kuma3さんのコメント
>|javascript| document.getElementsByName('kaisu1')[0].value ||< おっと、これで取れるんだ <tt>:-O</tt>

2 ● a-kuma3
●249ポイント ベストアンサー

こんな感じでどうでしょう。

<html><head><script>
function getKaisu(id) {
 var sel = document.getElementById(id);
 var index = sel.selectedIndex;
 return parseInt(sel.options[index].value);
}
function sortTable(){
 var kaisu1 = getKaisu("kaisu1");
 var kaisu2 = getKaisu("kaisu2");

 // シャッフルする意味が無い
 if (kaisu1 == kaisu2) {
 return;
 }
 // kaisu1 が小さくなるようにする
 if (kaisu1 > kaisu2) {
 var n = kaisu2;
 kaisu2 = kaisu1;
 kaisu1 = n;
 }
 var tabs = document.getElementsByTagName('TABLE');
 var tab = tabs[0];
 for (var i = 0 ; i < 100 ; ++i) {
 var index = kaisu1 + Math.floor((kaisu2 - kaisu1 + 1) * Math.random());
 var trs = document.getElementsByTagName('tr');
 var tr = trs[index];
 tr.parentNode.insertBefore(tr, trs[kaisu1]);
 }
}
</script>
</head>
<body>回数範囲選択
<select id="kaisu1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>?
<select id="kaisu2">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<input type="button" value="をシャッフル表示" onclick="sortTable()">
<table>
<tr><td>回数</td><td></td></tr>
<tr><td>1</td><td>a</td></tr>
<tr><td>2</td><td>b</td></tr>
<tr><td>3</td><td>c</td></tr>
<tr><td>4</td><td>d</td></tr>
</table></body></html>

スクリプトの部分に、それなりに手を入れました。
HTML の部分は、<select> の name 属性を、id 属性に変えてます。
回数1と回数2の大きさは、どちらが大きくても動作するようにしてます。


jsFiddle で試したのが、こちらです。
http://jsfiddle.net/a_kuma3/Q9BMX/

動作が分かりやすいように、回答で書いたコードと以下の点が違っています。



質問の意図を取り違えていましたので、あらためての回答です。
回数範囲に関係なく、全シャッフルした後に、回数範囲以外の行を display: none しています。

<html><head><script>
function sortTable(){
 var tabs = document.getElementsByTagName('TABLE');
 var tab = tabs[0];
 var bodies = Array.prototype.slice.apply(tab.getElementsByTagName('tr'));
 for (var r = bodies.length; r > 0; r--) {
 var index = Math.floor((r - 1) * Math.random()) + 1; // こうしないと、先頭行も対象になってしまいます
 tab.appendChild(bodies[index]);
// bodies.splice(index, 1); この処理は必要ないです
 }
 /* ここまでは、ほとんど同じです */


 var kaisu1 = document.getElementsByName('kaisu1')[0].value;
 var kaisu2 = document.getElementsByName('kaisu2')[0].value;
 if (kaisu1 > kaisu2) {
 var n = kaisu2;
 kaisu2 = kaisu1;
 kaisu1 = n;
 }
 var bodies = Array.prototype.slice.apply(tab.getElementsByTagName('tr'));
 for (var i = 1 ; i < bodies.length ; ++i) {
 var kaisu = parseInt(bodies[i].firstChild.innerHTML);
 if (kaisu < kaisu1 || kaisu2 < kaisu) {
 bodies[i].style.display = "none";
 }
 }

}</script></head>
<body>回数範囲選択
<select name="kaisu1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>?
<select name="kaisu2">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<input type="button" value="をシャッフル表示" onclick="sortTable()">
<table>
<tr><td>回数</td><td></td></tr>
<tr><td>1</td><td>a</td></tr>
<tr><td>2</td><td>b</td></tr>
<tr><td>3</td><td>c</td></tr>
<tr><td>4</td><td>d</td></tr>
</table></body></html>

質問のままのコードだと、先頭行までシャッフルの対象になってしまうので、少しだけ変更しています。

jsFiddle で確認したのが、こちらになります。
http://jsfiddle.net/a_kuma3/sWNdx/


takaniiさんのコメント
ありがとうございます。 回数範囲を1-2にして tableが以下の時でシャッフルした場合 <table> <tr><td>回数</td><td></td></tr> <tr><td>1</td><td>a</td></tr> <tr><td>2</td><td>b</td></tr> <tr><td>2</td><td>b</td></tr> <tr><td>3</td><td>c</td></tr> <tr><td>4</td><td>d</td></tr> </table> 回数が1-2の間に当てはまる1行目から3行目までシャッフルして欲しいのですがどのようにすればいいでしょうか?

takaniiさんのコメント
あれ なんかtableが表示されてしまいますね

a-kuma3さんのコメント
質問の内容を勘違いしてました(ぼくだけじゃないみたいですが)。 よく見たら、TABLE に「回数」ってありますよね。 補足に書かれた内容だったら、あまり難しく考えずに、全シャッフル(今のまま)してから、範囲に外れるものを display: none; していけば良さそうです。

a-kuma3さんのコメント
というわけで、回答に追記しました。

takaniiさんのコメント
ありがとうございます。 今ソースを見ましたところ >|html| <tr> <td>1</td> <td>hoge</td> <td>hoge</td> </tr> <tr> <td>2</td> <td>hoge</td> <td>hoge</td> </tr> <tr> <td>3</td> <td>hoge</td> <td>hoge</td> </tr> <tr> <td>4</td> <td>hoge</td> <td>hoge</td> </tr> ||< というように改行されておりました 各trの中の一番最初のtdの値を取得してくるにはどのようにすればいいのでしょうか? 度々すみません

a-kuma3さんのコメント
>> 各trの中の一番最初のtdの値を取得してくるにはどのようにすればいいのでしょうか? << おっと。 書き直したコードの以下の行を、 >|| var kaisu = parseInt(bodies[i].firstChild.innerHTML); ||< このように変更してください。 >|| var kaisu = parseInt(bodies[i].cells[0].innerHTML); ||< firstChild → cells[0] です。

質問者から

選択範囲の回数をtableの一行目から探索して
例えば 以下のテーブルで回数選択を1-2にしてシャッフルした場合
1 a
2 b
2 c
3 b
1行目から3行目までをシャッフルして表示し
範囲選択外のテーブルはdisplay:none;して欲しいのですが
どのように書けばいいでしょうか?


関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ