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

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

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

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

HTML

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

Q&A

1回答

432閲覧

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';
guest

回答1

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

総合スコア117548

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

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

YuRyo8586

2025/04/14 03:06

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問