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

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

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

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

Q&A

解決済

3回答

914閲覧

setTimeout関数を用いた制限時間の処理

aae_11

総合スコア178

JavaScript

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

1グッド

0クリップ

投稿2019/08/18 00:28

編集2019/08/18 05:04

以下のコードは、タイピングゲーム作成中のコードなのですが、うまくいかない点があり、質問させて貰いました。

'use strict'; { let words = ['blue','apple','sky','middle','set']; let word; let isPlaying = false; let loc = 0; let target; let letter_count = 0; let miss_count = 0; let miss_label; let letter_label; let timeLimit; timeLimit = 3 * 1000; let start_time; let time_label = document.getElementById('time_left'); window.addEventListener('click',() => { if(isPlaying == true){ return; } isPlaying = true; letter_label = document.getElementById('Letter_label'); miss_label = document.getElementById('Letter_miss_label'); target = document.getElementById('top_word'); word = words[Math.floor(Math.random() * words.length)]; target.textContent = word; start_time = Date.now(); const time_out_id = setTimeout(() => { let time_left = start_time + timeLimit - Date.now(); time_label.textContent = (time_left / 1000) .toFixed(2); },10); console.log(time_out_id); }); window.addEventListener('keyup', e => { if(isPlaying === true){ let placeholder = ''; if(e.key == word[loc]){ loc++; letter_count += 1; console.log(letter_count); letter_label.textContent = letter_count; for(let i = 0; i < loc; i++){ placeholder += '_'; } console.log(word.substring(loc)); console.log(placeholder); target.textContent = placeholder + word.substring(loc); }else{ miss_count++; miss_label.textContent = miss_count; } if(loc == word.length){ word = words[Math.floor(Math.random() * words.length)]; target.textContent = word; loc = 0; } } }); }
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="css/typing.css"> <title>Document</title> </head> <body> <h1 id="top_word">click to start</h1> <p class="letter_content"> Letter count:<span id="Letter_label">0</span>, Miss count:<span id="Letter_miss_label">0</span>, Time left:<span id="time_left"></span> </p> <script src="js/typing.js"></script> </body> </html>

うまくいかない点は、以下の部分です。

const time_out_id = setTimeout(() => { let time_left = start_time + timeLimit - Date.now(); time_label.textContent = (time_left / 1000) .toFixed(2); },10);

ここの部分は制限時間を設定する際のコードなのですが、setTimeout関数がうまく作動しておらず、console.log(time_left)で確認した所、一度しか出力しないため、時間が減少しないといった状態になっています。
ここの部分を解決する為、ご助言頂けましたら幸いです。
よろしくお願いします。

追記です
以下のコードを参考にして作ってみたのですが、以下のコードではsetTimeout関数によって制限時間を作成する処理が可能となっております。
以下のコードでは、可能で自分のコードではできない理由が分からないため、原因を教えていただければ幸いです。
※以下のコードでは、組み込んでいるHTMLファイルが自分のJSファイルとは異なります。

'use strict'; { const words = [ 'apple', 'sky', 'blue', 'middle', 'set', ]; let word = words[Math.floor(Math.random() * words.length)]; let loc; let score; let miss; const timeLimit = 3 * 1000; let startTime; const target = document.getElementById('target'); const scoreLabel = document.getElementById('score'); const missLabel = document.getElementById('miss'); const timerLabel = document.getElementById('timer'); let isPlaying = false; function updateTarget(){ let placeholder = ''; for(let i = 0; i < loc; i++){ placeholder += '_'; } target.textContent = placeholder + word.substring(loc); } function showResult(){ const accuracy = score + miss === 0 ? 0 : score / (score + miss) * 100; alert(`${score} letters, ${miss} misses, ${accuracy . toFixed(2)}% accuracy!`); } function updateTimer(){ const timeLeft = startTime + timeLimit - Date.now(); console.log(timeLeft); timerLabel.textContent = (timeLeft / 1000).toFixed(2); const timeoutId = setTimeout(() => { updateTimer(); },10); if(timeLeft < 0){ isPlaying = false; clearTimeout(timeoutId); setTimeout(() => { showResult(); },100); timerLabel.textContent = '0.00'; target.textContent = 'click to replay'; } } window.addEventListener('click', () => { if(isPlaying === true){ return; } isPlaying = true; loc = 0; score = 0; miss = 0; scoreLabel.textContent = score; missLabel.textContet = miss; word = words[Math.floor(Math.random() * words.length)]; updateTarget(); startTime = Date.now(); console.log(startTime); updateTimer(); }); window.addEventListener('keyup',e =>{ if(isPlaying !== true){ return; } if(e.key === word[loc]){ loc++; if(loc === word.length){ word = words[Math.floor(Math.random() * words.length)]; loc = 0; } score++; scoreLabel.textContent = score; updateTarget(); }else{ miss++; missLabel.textContent = miss; } }); }
toll_tree👍を押しています

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

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

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

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

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

guest

回答3

0

setTimeout関数以前にid="time_left"id="top_word"が存在しないため
setTimeout関数部分を修正してもこのプログラムは動作しないので
setTimeout関数以前の問題です。

投稿2019/08/18 00:42

yasutomi

総合スコア2937

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

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

aae_11

2019/08/18 00:56 編集

ご回答ありがとうございます。 質問に載せました、HTMLコードなのですが、違うファイルのコードを載せてしまっていた為、HTMLコードの方、修正しておきました。
guest

0

文脈から察するに、繰り返しsetTimeout内の関数を実行したいということでいいでしょうか?
それだとsetTimeoutではなくsetInterval関数を使わないと繰り返し実行されません。

投稿2019/08/18 00:34

wintermaples

総合スコア116

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

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

aae_11

2019/08/18 04:59

ご回答ありがとうございます。 >setTimeoutではなくsetInterval関数を使わないと繰り返し実行されません。 こちらの点に関してなのですが、全く同じコードではないのですが、setTimeout関数を使った制限時間を設定する処理を真似てみて、作ってみたのですが、自分の試したコードでは何故か、できないといった状態になってしまっております。
aae_11

2019/08/18 05:06

参考にさせて頂いたコードの方も、質問本文に載せさせて頂きましたので、チェック頂けたら幸いです
guest

0

自己解決

const time_out_id = setTimeout(() => { let time_left = start_time + timeLimit - Date.now(); time_label.textContent = (time_left / 1000) .toFixed(2); },10);

こちらの処理では、setTimeout関数により一度のみしか、実行されないことにより、 time_label.textContentに設定した時間が減少しないといったことが原因でした。
その為、以下のように関数にsetTimeout関数をまとめ、clickイベント内で、updateTime関数を呼び出すこちによって解決しました。

js

1 2 function updateTime(){ 3 4 let time_left = start_time + timeLimit - Date.now(); 5 time_label.textContent = (time_left / 1000) .toFixed(2); 6 7 const time_out_id = setTimeout(() => { 8 updateTime(); 9 },10); 10 11 }

投稿2019/08/18 05:54

aae_11

総合スコア178

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問