質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

2回答

1159閲覧

JavaScriptで16マスルーレットを作成したい(まずはjqueryを使わずに)。

YuRyo8586

総合スコア6

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

1グッド

1クリップ

投稿2025/04/13 22:03

JavaScriptで下の画像のような16マスのルーレットを作りたいと思っています。
最終的にはjqueryを使って作成したいのですが、まずはjqueryを使わずに作成を希望しています。
イメージ説明

満たすべき要件は以下の通りです。
1.ルーレットの目を16個作成する
2.スタートボタンを押すとルーレットが回転する
3.回転中はスタートボタンを押せなくする(ストップボタンで再び押せるようになる)
4.ルーレットの回転にランダム要素を組み込む
5.ルーレットが回っているときに、ストップボタンを押すとルーレットが止まる
6.一度ストップボタンで停止した目は次回以降は停止しない
7.スタートとストップを16回の繰り返しで、全ての目に停止する
8.16回停止後はスタートボタンが押せなくなる(リセットボタンで押せるようになる)
9.過去に停止した目が何か、ユーザに分かるようにする(目に色がつくなど)
10.リセットボタンを押すと初期表示の状態に戻る(もしルーレットが回っている場合はルーレットの回転が止まり、初期表示の状態になる)
11.(ソースコード)比較演算子は、「===」や「!==」を利用すること

現在、以下のようなコードを書くところまでは至っているのですが、
その後がどのように書けばいいかわからず躓いています。

javascript

1コード 2```<!DOCTYPE html> 3<html lang="ja"> 4 <head> 5 <meta charset="UTF-8"> 6 <title>ルーレット</title> 7 <style> 8 table{ 9 text-align: center; 10 margin-bottom:30px; 11 } 12 </style> 13 <script> 14 var interval; 15 var start_flag=false; 16 var array=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]; 17 var n; 18 function start(){ 19 if(start_flag===false){ 20 interval=setInterval(revolution,200); 21 start_flag=true; 22 document.getElementById('start').disabled=true; 23 } 24 } 25 function revolution(){ 26 n=Math.floor(Math.random()*array.length); 27 var select=document.getElementsByTagName('td'); 28 select.n.backgroundColor="#DF543A"; 29 } 30 function stop(){ 31 clearInterval(interval); 32 start_flag=false; 33 document.getElementById('start').disabled=false; 34 } 35 function reset(){ 36 clearInterval(interval); 37 start_flag=false; 38 var reverse=document.getElementById('roulette'); 39 reverse.style.backgroundColor='#ffffff'; 40 document.getElementById('start').disabled=false; 41 } 42 window.onload=function(){ 43 var revStart=document.getElementById('start'); 44 revStart.addEventListener('click',start,false); 45 var revStop=document.getElementById('stop'); 46 revStop.addEventListener('click',stop,false); 47 var revReset=document.getElementById('reset'); 48 revReset.addEventListener('click',reset,false); 49 } 50 </script> 51 </head> 52 <body> 53 <table border="1" width="200" height="200" id="roulette"> 54 <tr> 55 <td>1</td> 56 <td>2</td> 57 <td>3</td> 58 <td>4</td> 59 </tr> 60 <tr> 61 <td>5</td> 62 <td>6</td> 63 <td>7</td> 64 <td>8</td> 65 </tr> 66 <tr> 67 <td>9</td> 68 <td>10</td> 69 <td>11</td> 70 <td>12</td> 71 </tr> 72 <tr> 73 <td>13</td> 74 <td>14</td> 75 <td>15</td> 76 <td>16</td> 77 </tr> 78 </table> 79 <div id="button"> 80 <button id="start">スタート</button> 81 <button id="stop">ストップ</button> 82 <button id="reset">リセット</button> 83 </div> 84 </body> 85</html> 86 87恐縮ですが、アドバイスを頂きたく、何卒よろしくお願いいたします。
maisumakun👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2025/04/13 23:21

> 最終的にはjqueryを使って作成したいのですが、まずはjqueryを使わずに作成を希望しています。 わざわざそのような手順を取りたい理由は何でしょうか? (jQueryなしで完成させたものを、ことさらにjQueryで書き直す理由がわからないです)
YuRyo8586

2025/04/13 23:23

個人的な意向としか言えないです。 まずはjqueryなしで作成を理解したく、その後jqueryでの作成を理解したいという感じです。
maisumakun

2025/04/13 23:48

あと、現状のコードでは「何ができていて」「どんな箇所で詰まっている」という状況でしょうか。
utm.

2025/04/14 01:50

いくつか質問をしていますが最終的な目標があるはずです。背景情報を質問に記載する方が良いのではないかと思います。 JavaScriptで書いてみてjQueryに書き換えるということで、実際にしたいことはなんでしょうか。 プログラムの完成と技術の取得は分けて考えた方がいいです。 jQueryの基礎的なこと、内部構造に関心があるのであれば、JavaScriptのMDNなどのリファレンスを読んで、どういうAPIや文法があるのかを知った方が良いです。 それがつまらないので、ソースコードを実際に書いているのであれば、ソースコードをクレクレするのもいいかもしれませんが、そのコードを見てこれがなぜ動いてるのか、ここはどういう意味なのか、と自発的に興味を持つことが大事です。 興味を持つのが学習の1番の原動力であり、あなたの身になるはずです。 与えられた課題をただ捌き、与えられた情報をただ受け取るだけで、本当に学習になっていますか。 また、このサイトではソースコードの作成依頼は非推奨です。 何が分からなくてどこで困っているのかを明確にしてください。 https://teratail.com/help/question-tips あなたが今さしあたっている問題をまずひとつずつ解決すべきです。 ランダムなマスに色をつけられるが、本来次の色付けの際に色を戻すべき処理があるはずなのに、無いなど。 わざわざ質問をしなくても、この問題を解決出来るようにも思います。 もし、そのレベルよりもっと前の段階で、このプログラムがなぜ動いているのか分からないのであれば、単純に、色を付ける方法、時間ごとに切り替える方法と分割して問題を捉えたら良いと思います。 そもそもとして学習の方法が分からないのであれば、それを問うべきじゃないでしょうか。 最終的に何をしたいのですか?単に質問を投稿してみているだけ、という訳では無いですよね。
YuRyo8586

2025/04/14 03:05

失礼いたしました。 目的は、現在はプログラミングのスキルを付けることです。 たしかに、utm.さんがおっしゃるように、ソースコードをクレクレしている状況になってしまっているような点は反省します。 現状の問題点としては、まずはセルに色がつかない、ランダムにセルを選択してそこに色をつけたいという点です。 至らない点が多く申し訳ございません。
utm.

2025/04/14 03:34

ありがとうございます。 であれば、 revolution関数の実装を見直してみてください。 document.getElementsByTagNameでかえってくるHTMLコレクションという配列風のオブジェクトなので、nというプロパティアクセスではなく、select[n]としてやらねばなりません。styleプロパティは他の行で使っているので使い方は分かっているはずです。 オブジェクトの扱い方について少し理解が浅いのかもしれません。 以下蛇足 ちょっと深いので気にしなくていいですが、JavaScriptの配列は文字列を[]で書く方法とメソッドで書くパターンがありますが、数値で後者は使えません また、現状気にしなくていいと思いますが、関数をモジュールとして考えた時に乱数を配列のインデックスとして使うのであれば、その配列と範囲の整合性を取るような書き方に出来れば望ましいと思います。
YuRyo8586

2025/04/14 11:59

ありがとうございます。 function revolution(){ n=Math.floor(Math.random()*array.length); var select=document.getElementsByTagName('td'); select[n].style.backgroundColor="#DF543A"; } とrevolution関数を書いたところ、セルに色が付くようになりました。 しかし、ランダムに選ばれたセルに全て色がついてしまいます。 また、リセットボタンを押したら色が付いたセルの色が消えるよう、 function reset(){ clearInterval(interval); start_flag=false; var reverse=document.getElementById('roulette'); reverse.style.backgroundColor=''; document.getElementById('start').disabled=false; } という関数を書いているのですが、リセットボタンを押してもセルの色が消えないです。
melian

2025/04/14 13:45

> ランダムに選ばれたセルに全て色がついてしまいます。 デフォルトの background color に戻す処理がありませんので、そうなってしまいます。例えば、ランダムに選んだセルのインデックス(n)を保存しておいて、次のセルの選択時に保存しておいたインデックスのセルの background color を元に戻すなどの処理を追加する必要があります。 > リセットボタンを押したら色が付いたセルの色が消えるよう、 > var reverse=document.getElementById('roulette'); ID "roulette" は table 要素に付いていますので table 要素の background color がリセットされることになります。(実際には全ての td 要素の background color をリセットする必要があります)
melian

2025/04/14 14:03

ところで、これは CodeCamp の課題の様ですね。 CodeCamp Webマスターコース JavaScript 提出課題 ルーレット(最終更新日 2020年10月05日) https://qiita.com/Charry/items/9e906336df8390026dcd > 当方は2月から2ヶ月間CodeCampのWebマスターコースを受講しました。 > > 課題の内容 > jQueryでWeb上で動くルーレットを作成する。 CodeCamp に関しては「Google口コミ」に以下の様な寸評が付けられていて(6年前)、これが事実だとすればスキルアップには向かない様に思えます。 https://maps.app.goo.gl/3JPEJ9kz4nX6dx6i8 > 教材も更新している様子はなく、未だに消費税計算が5パーセントのままになっている
utm.

2025/04/14 16:49

そうか、確かにvarとか、非推奨な書き方が多いものの、これでお金取ってるんだもんな、となんか急に現実に引き戻されました。 GPTの登場でプログラミングスクールとかが淘汰されるのでは、的な時代でこういう商売が成立しているのを考えると、人間の行動は奥が深いですな...
YuRyo8586

2025/04/14 20:50

私は別のプログラミングスクールを受講しており、月額も安いためあまり不満は多く無いのですが、今度思うところを伝えてみようと思います。 >デフォルトの background color に戻す処理がありませんので、そうなってしまいます。例えば、ランダムに選んだセルのインデックス(n)を保存しておいて、次のセルの選択時に保存しておいたインデックスのセルの background color を元に戻すなどの処理を追加する必要があります。 インデックスの保存となると、IndexedDB?というものを使うのでしょうか? >ID "roulette" は table 要素に付いていますので table 要素の background color がリセットされることになります。(実際には全ての td 要素の background color をリセットする必要があります) function reset(){ clearInterval(interval); start_flag=false; var reverse=document.getElementByByTagName('td'); reverse.style.backgroundColor='#ffffff'; document.getElementById('start').disabled=false; } という風に、td要素を取得してbackgroundColorを白にするようにコードを書いたのですが、リセットボタンを押してもセルが白にならないですね…
utm.

2025/04/15 01:05

最終的に自走してプログラムを作成できるようになるために 基本的なアルゴリズムの理解 データ構造上の用語理解(発展として効率的なアクセス) オブジェクト指向(あるいはオブジェクト)によるデータの管理の理解(必須では無いものの、活用出来る場面が多い) という基礎的な部分を固める必要がありそうです ※プログラム上のモジュールがシンプルな場合
melian

2025/04/15 01:24 編集

> インデックスの保存となると、IndexedDB?というものを使うのでしょうか? いえ、データベースのインデックスではなく、配列のインデックスです。具体的にはランダムに選んだ数値で、変数 n を指します。 > td要素を取得してbackgroundColorを白にするようにコードを書いたのですが、 以前の utm. さんのコメントで「document.getElementsByTagNameでかえってくるHTMLコレクションという配列風のオブジェクトなので〜」とありました。それを思い出してください。
YuRyo8586

2025/04/15 12:11

>いえ、データベースのインデックスではなく、配列のインデックスです。具体的にはランダムに選んだ数値で、変数 n を指します。 ランダムに選んだ数値の変数nが、一度色が付いた後、元の色に戻るという感じでしょうか…? >以前の utm. さんのコメントで「document.getElementsByTagNameでかえってくるHTMLコレクションという配列風のオブジェクトなので〜」とありました。それを思い出してください。 一度以下のようなコードを書いたのですが、ダメでした…。 function reset(){ clearInterval(interval); start_flag=false; n=array.length; var reverse=document.getElementByByTagName('td'); reverse[n].style.backgroundColor='#ffffff'; document.getElementById('start').disabled=false; }
melian

2025/04/15 14:37

> n=array.length; > var reverse=document.getElementsByTagName('td'); > reverse[n].style.backgroundColor='#ffffff'; ここでreverseオブジェクト(インスタンス)はHTMLCollection型で配列風のオブジェクトです。(「配列風」ですが、mapやfilterメソッドなどは提供されていません) HTMLCollection - Web API | MDN https://developer.mozilla.org/ja/docs/Web/API/HTMLCollection 変数arrayの要素数は16なのでreverse[n]はreverse[16]ということになりますが、配列のインデックスは0から始まりますのでreverse[16]はundefinedです。 全てのtd要素のbackgroudColorを#ffffffに変更する処理を一つ一つ丁寧に書き下すと以下になりますが、これを繰り返し(ループ)処理にまとめることができるということは理解できますでしょうか? この様な場合に利用する構文は何なのかを思い出してみてください。 reverse[0].style.backgroundColor='#ffffff'; reverse[1].style.backgroundColor='#ffffff';       : reverse[14].style.backgroundColor='#ffffff'; reverse[15].style.backgroundColor='#ffffff';
YuRyo8586

2025/04/15 22:08 編集

>変数arrayの要素数は16なのでreverse[n]はreverse[16]ということになりますが、配列のインデックスは0から始まりますのでreverse[16]はundefinedです。 全てのtd要素のbackgroudColorを#ffffffに変更する処理を一つ一つ丁寧に書き下すと以下になりますが、これを繰り返し(ループ)処理にまとめることができるということは理解できますでしょうか? この様な場合に利用する構文は何なのかを思い出してみてください。 reverse[0].style.backgroundColor='#ffffff'; reverse[1].style.backgroundColor='#ffffff';       : reverse[14].style.backgroundColor='#ffffff'; reverse[15].style.backgroundColor='#ffffff'; ありがとうございます。 以下のようにfor文を追加したところ、リセットボタンを押すとセルの色が全て消えるようになりました。 function reset(){ clearInterval(interval); start_flag=false; var reverse=document.getElementsByTagName('td'); for(var i=0;i<=array.length;i++){ reverse[i].style.backgroundColor='#ffffff'; } document.getElementById('start').disabled=false; } 続いて解決したいのが、前のコメントでも書いているのですが、 スタートボタンを押した際にランダムにセルが選択された際、全てのセルに色が付いてしまう点ですね…。
YuRyo8586

2025/04/16 11:19

申し訳ありません。 まずは自分で考えてみることでしょうか。
YuRyo8586

2025/04/16 12:18

失礼します。 以下のような感じでコードを書き換えたところ、 選択されたセルに色が付いたままになるということはなくなったのですが、 複数のセルに同時に色が付くようになってしまい、 未だに1つずつセルに色が付いては消えるという感じには至っていません…。 function start(){ if(start_flag===false){ interval=setInterval(revolution,10); start_flag=true; document.getElementById('start').disabled=true; } } function revolution(){ n=Math.floor(Math.random()*(array.length+1)); var select=document.getElementsByTagName('td'); if(select[n].style.backgroundColor===''){ select[n].style.backgroundColor="#DF543A"; }else{ select[n].style.backgroundColor=''; } }
melian

2025/04/16 20:11

revolution()関数ですが、以下の手順で処理が行われています。 1. n=Math.floor(Math.random()*(array.length)) でランダムな数値を選択しています。例として、3が選ばれたとします(変数nの値が3になります) 2. "4"のマス目(td要素)のbackground colorが変更されます(配列のインデックスは0から始まることを思い出してください) 3. 10ms 後にrevolution()関数が再度実行されます 4. ランダムな数値が選ばれてnの値が更新されます。これを10だとします。 5. "11"のマス目(td要素)のbackground colorが変更されることになるので、2. でbackground colorを変更した"4"のマス目の色はそのままになります revolution()関数の最初でnの値を更新してしまっているので、前回に選んだランダムな数値(上記の例では 1. の3という値)が不明になっているのです。 なので、最初にselect[n](td要素)のbackground colorを元に戻してからnの値を更新する必要があります。ですが、一つ問題があって、初回にrevolution()関数を実行する際にはnの値はundefindなので select[n].style.backgroundColor="#DF543A"; を実行するとエラーになります。
YuRyo8586

2025/04/16 22:03

ありがとうございます。 一度ランダムに選んだセルに色をつける ↓ そのセルの色を元に戻す ↓ 違うセルをランダムに選んで色をつける ↓ 以下繰り返し だと思うのですが、 一度色が付いたセルの色を元に戻す場合、.removeを使ったりするのでしょうか? select[n].remove… という感じでしょうか…?
melian

2025/04/17 00:02

> 一度色が付いたセルの色を元に戻す場合、.removeを使ったりするのでしょうか? ご自身で書かれている通りでよいかと思います。 select[n].style.backgroundColor='';
YuRyo8586

2025/04/17 11:58

すみません、調べて以下のようにコードを書いたのですが、 やはり一度色が付いたセルの色が戻らない&エラーが出ます。 function revolution(){ n=Math.floor(Math.random()*(array.length+1)); var select=document.getElementsByTagName('td'); select[n].style.backgroundColor="#DF543A"; if(select[n].style.backgroundColor="#DF543A"){ scene.setTimeout(function(){ select[n].style.backgroundColor=""; },10); } }
melian

2025/04/17 15:09

> 最初にselect[n](td要素)のbackground colorを元に戻してからnの値を更新する必要があります。ですが、一つ問題があって、初回にrevolution()関数を実行する際にはnの値はundefindなので select[n].style.backgroundColor=''; を実行するとエラーになります。 前回のコメントの通りに書くと以下の様になりますが、これはエラーになります。("var n;"として宣言しているので変数nはundefinedです) この問題を解決するためには分岐処理を追加する必要があります。(他にも適当な値でnを初期化しておく処理が必要) function revolution(){  var select=document.getElementsByTagName('td');  select[n].style.backgroundColor='';  n=Math.floor(Math.random()*(array.length));  select[n].style.backgroundColor="#DF543A"; } ところで、スクールの課題であれば提出期限があるはずです。ルーレットの回転処理ができたとしても、更に以下の処理を組み込むには時間が足りないのではないでしょうか。 > 6. 一度ストップボタンで停止した目は次回以降は停止しない > 7. スタートとストップを16回の繰り返しで、全ての目に停止する > 8. 16回停止後はスタートボタンが押せなくなる(リセットボタンで押せるようになる) > 9. 過去に停止した目が何か、ユーザに分かるようにする(目に色がつくなど) 既に回答が付いていますので、そちらのコードを解読する方が効率的かと思います。
YuRyo8586

2025/04/17 20:50

ありがとうございます。 revolution関数をご記載いただいたように変更&最初に定義したvar n;を、 var n=Math.floor(Math.random()*(array.length+1)); と書き換えると、ランダムに選択されたセルに色が付いたまま残るということがなくなりました。 スクールの課題ではありますが、提出期限は特に設けられていません。 ですので、考えつつアドバイスを頂きながら、仕上げていければと存じます。
melian

2025/04/17 21:41

> var n=Math.floor(Math.random()*(array.length+1)); array.length+1 とする場合、n の値が16になることがあります。そのため、select[n].style.backgroundColor=''; でエラーが発生することになります。(以前のコメントで述べた通り、td要素の個数は16なので select[16] は undefined になるからです) 先述のコメントは、start() 関数内で n を null や -1 などの値(個数としては取り得ない値)で初期化しておいて、revolution()関数で n の値をチェックして background color を変更するのかどうかを判断する処理を追加します、という意味だったのです。
YuRyo8586

2025/04/17 21:52

array.length+1 としておりますが、+1を書かない場合、 スタートボタンを押した際に16のセルが選択されませんでした。 そこで、+1を書くと16のセルも選択されるようになり、 また現在エラーも発生していないようなので、この形にしているのですが、 あまりよろしくないでしょうか?
melian

2025/04/17 22:23

はい、n が16の場合は以下のエラーが発生します。(select[16]がundefinedだからです) > Uncaught TypeError: Cannot read properties of undefined (reading 'style') ブラウザのDevTools(開発者ツール)で確認できるかと思います。
YuRyo8586

2025/04/18 11:49

かしこまりました、ちょっと考えます。
YuRyo8586

2025/04/18 12:39

失礼します。 ひとまず、array.length+1とするとエラーが出る件については後で対応しようと思いますm(__)m 次に、ルーレットでストップボタンを押したときに止まったセルの色を、 ルーレット回転中の色とは違う色にするため、 ストップボタンを押したときの関数として function stop(){ clearInterval(interval); start_flag=false; document.getElementById('start').disabled=false; var select=document.getElementsByTagName('td'); if(select[n].style.backgroundColor==="#DF543A"){ select[n].style.backgroundColor='#1B3DB0'; } } としたのですが、特に別の色に変化しません。 何が問題でしょうか?
melian

2025/04/18 13:01

> if(select[n].style.backgroundColor==="#DF543A"){ "#DF543A" という表記形式では color の値を比較することができないためで、この様な場合はRGB値を使用します。 if(select[n].style.backgroundColor === 'rgb(223, 84, 58)'){
YuRyo8586

2025/04/18 13:21

ありがとうございます。 if文に入れる場合はRGB表記でないといけないのでしょうか?
melian

2025/04/18 13:26

現状ではそうなります。(Windows の IE だけは #XXXXXX での比較も可能です)
YuRyo8586

2025/04/21 11:14 編集

ありがとうございます。 RGB表記にすることで色が変化しました。 その後、ストップボタンを押して色が変わったセルはそのままその色を保存するため、 下記のようなコード(2つ目のif文)を書いたのですが、不十分でしょうか。 function stop(){ clearInterval(interval); start_flag=false; document.getElementById('start').disabled=false; var select=document.getElementsByTagName('td'); if(select[n].style.backgroundColor=== 'rgb(223, 84, 58)'){ select[n].style.backgroundColor='#1B3DB0'; } if(select[n].style.backgroundColor==='rgb(27, 61, 176)') { select[n].style.backgroundColor='#1B3DB0'; } }
guest

回答2

0

2.スタートボタンを押すとルーレットが回転する
4.ルーレットの回転にランダム要素を組み込む
の方法が思いつかず、 yambejpさんのコードは難しくて解読できない、といった状態で行き詰まっているという前提で、この部分の改善について回答します。

極力元のコードの変更が少ないようにはしています。
動いているが読みにくく複雑な記述になっている部分もありそうですが、それについては触れません。


まず、現状 n という変数で何番目かとか、arrayという変数で16マスを表したりしていますが、
このような変数で色々やりとりをするのは変数がどうなっているかを考える必要があるので難しいです。cssで見た目を変える方式をおすすめします。
具体的には、<td> タグが特定のclassを持っている時に色をつけるcssを<style> タグに追加します。

html

1<style> 2 table{ 3 text-align: center; 4 margin-bottom:30px; 5 } 6 td.current { 7 background-color: #DF543A; 8 } 9</style>

これによって、<td class="current"> となっている場合に背景色がつきます。

次に、ランダム選択する、という部分について、「配列から1つ選択する」という部分の処理がすこし複雑になるので、これを関数化します。ここでは choice() という名前にします。

javascript

1const choice = (elements) => { 2 const index = Math.floor(Math.random() * elements.length); 3 return elements[index]; 4};

最後に、スタートを押した後に繰り返し呼ばれる処理である revolution()の中身を変更します。
処理内容としては下記のとおりです

  • currentクラスがついているtdがあれば一旦currentクラスを削除
    • これによって直前にルーレットで選ばれていたマスの色がもとに戻ります
  • 全てのtdの中からランダムに1つ選ぶ
  • 選ばれたtdにcurrentクラスを付与する

javascript

1function revolution(){ 2 const currentTd = document.querySelector('td.current'); 3 if (currentTd) { 4 currentTd.classList.remove('current'); 5 } 6 const allTdElements = document.querySelectorAll('td'); 7 const choicedTd = choice(allTdElements); 8 choicedTd.classList.add('current'); 9}

修正後の全体としては下記のようになります。

html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>ルーレット</title> 6 <style> 7 table{ 8 text-align: center; 9 margin-bottom:30px; 10 } 11 td.current { 12 background-color: #DF543A; 13 } 14 </style> 15 <script> 16 const choice = (elements) => { 17 const index = Math.floor(Math.random() * elements.length); 18 return elements[index]; 19 }; 20 21 var interval; 22 var start_flag=false; 23 function start(){ 24 if(start_flag===false){ 25 interval=setInterval(revolution,200); 26 start_flag=true; 27 document.getElementById('start').disabled=true; 28 } 29 } 30 function revolution(){ 31 const currentTd = document.querySelector('td.current'); 32 if (currentTd) { 33 currentTd.classList.remove('current'); 34 } 35 const allTdElements = document.querySelectorAll('td'); 36 const choicedTd = choice(allTdElements); 37 choicedTd.classList.add('current'); 38 } 39 function stop(){ 40 clearInterval(interval); 41 start_flag=false; 42 document.getElementById('start').disabled=false; 43 } 44 function reset(){ 45 clearInterval(interval); 46 start_flag=false; 47 var reverse=document.getElementById('roulette'); 48 reverse.style.backgroundColor='#ffffff'; 49 document.getElementById('start').disabled=false; 50 } 51 window.onload=function(){ 52 var revStart=document.getElementById('start'); 53 revStart.addEventListener('click',start,false); 54 var revStop=document.getElementById('stop'); 55 revStop.addEventListener('click',stop,false); 56 var revReset=document.getElementById('reset'); 57 revReset.addEventListener('click',reset,false); 58 } 59 </script> 60 </head> 61 <body> 62 <table border="1" width="200" height="200" id="roulette"> 63 <tr> 64 <td>1</td> 65 <td>2</td> 66 <td>3</td> 67 <td>4</td> 68 </tr> 69 <tr> 70 <td>5</td> 71 <td>6</td> 72 <td>7</td> 73 <td>8</td> 74 </tr> 75 <tr> 76 <td>9</td> 77 <td>10</td> 78 <td>11</td> 79 <td>12</td> 80 </tr> 81 <tr> 82 <td>13</td> 83 <td>14</td> 84 <td>15</td> 85 <td>16</td> 86 </tr> 87 </table> 88 <div id="button"> 89 <button id="start">スタート</button> 90 <button id="stop">ストップ</button> 91 <button id="reset">リセット</button> 92 </div> 93 </body> 94</html>

投稿2025/04/18 11:04

Eggpan

総合スコア3257

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ざっくりこんな感じでしょうか?
選択されているとかすでに止まったのようなステータスの管理はクラスが楽です。
またボタンの管理は専用のユーザー関数を用意するとよいでしょう

html

1<style> 2table{ 3 text-align: center; 4 margin-bottom:30px; 5} 6.done:not(.active){ 7 background-Color:lightgray; 8} 9.active{ 10 background-Color:#DF543A; 11} 12</style> 13<script> 14window.addEventListener('DOMContentLoaded', ()=>{ 15 let timerId; 16 const setButtons=(start,stop,reset)=>{ 17 document.querySelector('#start').disabled=start; 18 document.querySelector('#stop').disabled =stop; 19 document.querySelector('#reset').disabled=reset; 20 }; 21 setButtons(false,true,true); 22 document.querySelector('#start').addEventListener('click',()=>{ 23 const elem=document.querySelector('.active'); 24 if(elem){ 25 elem.classList.remove('active'); 26 } 27 const select=document.querySelectorAll('td:not(.done)'); 28 setButtons(true,false,true); 29 timerId=setInterval(()=>{ 30 const n=Math.floor(Math.random()*select.length); 31 document.querySelector('.active')?.classList.remove('active'); 32 select[n].classList.add('active'); 33 },100); 34 }); 35 document.querySelector('#stop').addEventListener('click',()=>{ 36 document.querySelector('.active').classList.add('done'); 37 const select=document.querySelectorAll('td:not(.done)'); 38 setButtons(select.length===0,true,false); 39 clearInterval(timerId); 40 }); 41 document.querySelector('#reset').addEventListener('click',()=>{ 42 setButtons(false,true,true); 43 document.querySelectorAll('.active,.done').forEach(elem=>{ 44 elem.classList.remove('active'); 45 elem.classList.remove('done'); 46 }); 47 }); 48}); 49</script> 50<table border> 51 <tr> 52 <td>1</td> 53 <td>2</td> 54 <td>3</td> 55 <td>4</td> 56 </tr> 57 <tr> 58 <td>5</td> 59 <td>6</td> 60 <td>7</td> 61 <td>8</td> 62 </tr> 63 <tr> 64 <td>9</td> 65 <td>10</td> 66 <td>11</td> 67 <td>12</td> 68 </tr> 69 <tr> 70 <td>13</td> 71 <td>14</td> 72 <td>15</td> 73 <td>16</td> 74 </tr> 75</table> 76<div id="button"> 77 <button id="start">スタート</button> 78 <button id="stop">ストップ</button> 79 <button id="reset">リセット</button> 80</div>

jQuery版

上記書き直すとこう

html

1<style> 2table{ 3 text-align: center; 4 margin-bottom:30px; 5} 6.done:not(.active){ 7 background-Color:lightgray; 8} 9.active{ 10 background-Color:#DF543A; 11} 12</style> 13<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> 14<script> 15$(function(){ 16 let timerId; 17 const setButtons=(start,stop,reset)=>{ 18 $('#start').prop('disabled',start); 19 $('#stop').prop('disabled',stop); 20 $('#reset').prop('disabled',reset); 21 }; 22 setButtons(false,true,true); 23 $('#start').on('click',()=>{ 24 $('.active').removeClass('active'); 25 const select=$('td:not(.done)'); 26 setButtons(true,false,true); 27 timerId=setInterval(()=>{ 28 const n=Math.floor(Math.random()*select.length); 29 $('.active').removeClass('active'); 30 select.eq(n).addClass('active'); 31 },100); 32 }); 33 $('#stop').on('click',()=>{ 34 $('.active').addClass('done'); 35 const select=$('td:not(.done)'); 36 setButtons(select.length===0,true,false); 37 clearInterval(timerId); 38 }); 39 $('#reset').on('click',()=>{ 40 setButtons(false,true,true); 41 $('.active,.done').removeClass('active done'); 42 }); 43}); 44</script> 45<table border> 46 <tr> 47 <td>1</td> 48 <td>2</td> 49 <td>3</td> 50 <td>4</td> 51 </tr> 52 <tr> 53 <td>5</td> 54 <td>6</td> 55 <td>7</td> 56 <td>8</td> 57 </tr> 58 <tr> 59 <td>9</td> 60 <td>10</td> 61 <td>11</td> 62 <td>12</td> 63 </tr> 64 <tr> 65 <td>13</td> 66 <td>14</td> 67 <td>15</td> 68 <td>16</td> 69 </tr> 70</table> 71<div id="button"> 72 <button id="start">スタート</button> 73 <button id="stop">ストップ</button> 74 <button id="reset">リセット</button> 75</div>

投稿2025/04/14 00:52

編集2025/04/14 01:25
yambejp

総合スコア117673

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YuRyo8586

2025/04/14 03:06

ありがとうございます。 本日帰宅後、詳しく拝見させていただきたく存じます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問