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

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

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

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

Q&A

解決済

1回答

2163閲覧

【javascript】カウントが0になったときの条件分岐の書き方がわからない

begine

総合スコア7

JavaScript

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

0グッド

0クリップ

投稿2020/06/27 08:52

編集2020/07/01 06:06

前提・実現したいこと

時間制限ありのクイズ問題を作成しているのですが、知識不足のため思ったように書くことができないので助けて欲しいです。

【大まかな流れ】

・ボタンクリックでクイズ画面に移動。

・画面の切り替わり後に、タイマーが起動してクイズに答えることができる。

・リザルトウィンドウを表示。

【教えて欲しい所】

クイズの問題に全て答えるか、
カウントダウンタイマーが0になるか、
のどちらかでリザルト画面を表示させたいのですが、書き方がわかりません。

main.js44行目のif(timeLeft < 0){}の中に書くのかな?と思い試していたのですが、解決できませんでした。

よろしくお願いします。

発生している問題

クイズの問題に全て答えるか、カウントダウンタイマーが0になるか、のどちらかでリザルト画面を表示させたいのですが、書き方がわからない

該当のソースコード

javascript

1 2{ 3 const btn = document.getElementById('btn'); 4 const timer = document.getElementById('timer'); //1 5 const sbtn = document.getElementById('sbtn'); //2 6 7 let startTime; //STARTボタンを押したときの時刻(宣言) 8 let timeLeft; //残り時間 9 const timeToCountDown = 3 * 1000; //1000 = 1秒 10 let timerId; //clearTimeoutの引数に渡す 11 12 13 function countDown() { // countDownの宣言 14 timerId = setTimeout (function() { 15 //timerIdをsetTimeoutの返り値として取得 次の処理を指定したミリ秒後に実行(1度だけ) 16 17 // const elapsedTime = Date.now() - startTime; 経過時間 = 現在時刻 - スタートした時間 18 // timeLeft = timeToCountDown - elapsedTime; 残り時間 = カウントダウン時間 - 経過時間 19 timeLeft = timeToCountDown - (Date.now() - startTime); 20 //elapsedTimeは、1度しか使わないので直接代入した↑ 21 22 if(timeLeft < 0){ //残り時間が0より小さくなったらclearTimeoutを呼ぶ(タイマー停止) 23 clearTimeout(timerId); 24 timeLeft = 0; //timeLeftを0にして、updateTimerで更新する 25 updateTimer(timeLeft); 26 return; //clearTimeout()したら次のcountDown()を呼び出したくないためreturnする 27 } 28 29 updateTimer(timeLeft); // 呼び出し(渡すミリ秒はtimerLeft) 30 countDown(); //countDownを再帰的に呼び出したいため、ここで呼ぶ。 31 }, 10); 32 } 33 34 sbtn.addEventListener('click', function() { //STARTボタンがクリックされたらタイマーON 35 startTime = Date.now(); // 押したときの時刻を取得 36 countDown(); /* カウントダウン機能は setTimeoutを使い再帰的に実行させるため countDown() という名前の別関数にする。*/ 37 }); 38 39 40 41 function setQuiz() { 42 isAnswered = false; 43 44 question.textContent = quizSet[currentNum].q; 45 46 while (choices.firstChild) { 47 choices.removeChild(choices.firstChild); 48 } 49 50 const shuffledChoices = shuffle([...quizSet[currentNum].c]); 51 shuffledChoices.forEach(choice => { 52 const li = document.createElement('li'); 53 li.textContent = choice; 54 li.addEventListener('click', () => { 55 checkAnswer(li); 56 }); 57 choices.appendChild(li); 58 }); 59 60 if (currentNum === quizSet.length - 1) { 61 btn.textContent = 'Show Score'; 62 } 63 64 } 65 66 setQuiz(); 67 68 btn.addEventListener('click', () => { 69 if (btn.classList.contains('disabled')) { 70 return; 71 } 72 btn.classList.add('disabled'); 73 74 if (currentNum === quizSet.length - 1) { 75 scoreLabel.textContent = `Score: ${score} / ${quizSet.length}`; 76 result.classList.remove('hidden'); 77 } else { 78 currentNum++; 79 setQuiz(); 80 } 81 }); 82} 83 84

試したこと

自分なりに試して書いていたのですが、解決できませんでした。

補足情報(FW/ツールのバージョンなど)

記述していただいたコードで解決できました。

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

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

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

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

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

guest

回答1

0

ベストアンサー

参考にどうぞ。(★が変更箇所です)

JavaScript

1'use strict'; 2 3{ 4 const question = document.getElementById('question'); 5 const choices = document.getElementById('choices'); 6 const btn = document.getElementById('btn'); 7 const result = document.getElementById('result'); 8 const scoreLabel = document.querySelector('#result > p'); 9 const timer = document.getElementById('timer'); //1 10 const sbtn = document.getElementById('sbtn'); //2 11 12 let startTime; //STARTボタンを押したときの時刻(宣言) 13 let timeLeft; //残り時間 14 const timeToCountDown = 3 * 1000; //1000 = 1秒 15 let timerId; //clearTimeoutの引数に渡す 16 17 /*constは初期化が必要 const X = 数値、もしくは初期化しない場合は let x; */ 18 19 function updateTimer(t) { //ミリ秒を渡すと、分や秒に直す。t でミリ秒を渡す。 20 const d = new Date(t); //渡されたtで、Dateオブジェクトを作る。 21 let m = d.getMinutes(); //このDateオブジェクトから「分や秒」を取り出す。 22 let s = d.getSeconds(); 23 let ms = d.getMilliseconds(); 24 m = ('0' + m).slice(-2); //文字列と数値を連結させると文字列になる。 25 s = ('0' + s).slice(-2); //文字列と数値を連結させると文字列になる。 26 ms = ('00' + ms).slice(-3); //文字列と数値を連結させると文字列になる。 27 timer.textContent = m + ':' + s + '.' + ms; //timerの中身を書き換え。 28 } 29 30 document.addEventListener('DOMContentLoaded', function() { 31 startTime = Date.now(); 32 countDown(); 33 }); 34 35 function countDown() { // countDownの宣言 36 timerId = setTimeout (function() { 37 //timerIdをsetTimeoutの返り値として取得 次の処理を指定したミリ秒後に実行(1度だけ) 38 39 // const elapsedTime = Date.now() - startTime; 経過時間 = 現在時刻 - スタートした時間 40 // timeLeft = timeToCountDown - elapsedTime; 残り時間 = カウントダウン時間 - 経過時間 41 timeLeft = timeToCountDown - (Date.now() - startTime); 42 //elapsedTimeは、1度しか使わないので直接代入した↑ 43 44 if(timeLeft < 0){ //残り時間が0より小さくなったらclearTimeoutを呼ぶ(タイマー停止) 45 clearTimeout(timerId); 46 timeLeft = 0; //timeLeftを0にして、updateTimerで更新する 47 updateTimer(timeLeft); 48 49 // ★時間切れになったら 50 btn.classList.remove('disabled'); // Nextボタンのdisabledを解除する 51 btn.textContent = 'Show Score'; // Nextボタンの表示は「Show Score」にする 52 currentNum = quizSet.length - 1; // 最終問題まで終わったテイにする 53 isAnswered = true; // 今表示されている問題は回答したテイにする(そうしないと時間切れなのに回答できてしまう) 54 55 return; //clearTimeout()したら次のcountDown()を呼び出したくないためreturnする 56 } 57 58 updateTimer(timeLeft); // 呼び出し(渡すミリ秒はtimerLeft) 59 countDown(); //countDownを再帰的に呼び出したいため、ここで呼ぶ。 60 }, 10); 61 } 62 63 sbtn.addEventListener('click', function() { //STARTボタンがクリックされたらタイマーON 64 startTime = Date.now(); // 押したときの時刻を取得 65 countDown(); /* カウントダウン機能は setTimeoutを使い再帰的に実行させるため countDown() という名前の別関数にする。*/ 66 }); 67 68 69 const quizSet = shuffle([ 70 {q: '世界で一番大きな湖は?', c: ['カスピ海', 'カリブ海', '琵琶湖']}, 71 {q: '2の8乗は?', c: ['256', '64', '1024']}, 72 {q: '次のうち、最初にリリースされた言語は?', c: ['Python', 'JavaScript', 'HTML']}, 73 ]); 74 let currentNum = 0; 75 let isAnswered; 76 let score = 0; 77 78 function shuffle(arr) { 79 for (let i = arr.length - 1; i > 0; i--) { 80 const j = Math.floor(Math.random() * (i + 1)); 81 [arr[j], arr[i]] = [arr[i], arr[j]]; 82 } 83 return arr; 84 } 85 86 function checkAnswer(li) { 87 if (isAnswered) { 88 return; 89 } 90 isAnswered = true; 91 92 if (li.textContent === quizSet[currentNum].c[0]) { 93 li.classList.add('correct'); 94 score++; 95 } else { 96 li.classList.add('wrong'); 97 } 98 99 btn.classList.remove('disabled'); 100 } 101 102 function setQuiz() { 103 isAnswered = false; 104 105 question.textContent = quizSet[currentNum].q; 106 107 while (choices.firstChild) { 108 choices.removeChild(choices.firstChild); 109 } 110 111 const shuffledChoices = shuffle([...quizSet[currentNum].c]); 112 shuffledChoices.forEach(choice => { 113 const li = document.createElement('li'); 114 li.textContent = choice; 115 li.addEventListener('click', () => { 116 checkAnswer(li); 117 if (currentNum === quizSet.length - 1) clearTimeout(timerId); // ★最終問題に回答したらタイマー止める 118 }); 119 choices.appendChild(li); 120 }); 121 122 if (currentNum === quizSet.length - 1) { 123 btn.textContent = 'Show Score'; 124 } 125 126 } 127 128 setQuiz(); 129 130 btn.addEventListener('click', () => { 131 if (btn.classList.contains('disabled')) { 132 return; 133 } 134 btn.classList.add('disabled'); 135 136 if (currentNum === quizSet.length - 1) { 137 scoreLabel.textContent = `Score: ${score} / ${quizSet.length}`; 138 result.classList.remove('hidden'); 139 } else { 140 currentNum++; 141 setQuiz(); 142 } 143 }); 144}

投稿2020/06/27 14:20

shun-K

総合スコア508

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

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

begine

2020/06/28 09:11

参考にさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問