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

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

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

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

Q&A

解決済

3回答

1769閲覧

Javascript SetInterval()で呼び出す関数のなかで変化した変数の値を取得したい

kaitouEx

総合スコア21

JavaScript

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

0グッド

0クリップ

投稿2020/04/08 02:16

##やりたいこと:
1~10までのランダムな数字を1.2秒ごとに4回画面上に表示し、かつ同時に合計値を表示したい。

##例:
3 5 2 8 の数字が1つずつ画面に現れ、最後に合計の数:18が表示されるようにしたい

##困っていること:
合計のsumに数値が足されず、正しい数が出ない。

##試したこと

  1. calc()の戻り値に合計対象である数字を指定して、呼び出し元のbtn_start()で合計しようとしたが、setInterval()のなかで関数に戻り値を持たせることができなかった

https://developer.mozilla.org/ja/docs/Web/API/Window/setInterval
上記URLに、「関数には引数が渡されず、また戻り値を想定していません。」と記載がある。

  1. calc()のなかでグローバル変数のsumに対して数値を追加しているが、0のまま。

(コード)

Javascript

1<!DOCTYPE html> 2<head> 3 <meta charset="utf-8"> 4 <title>そろばん</title> 5</head> 6<body> 7 <input type="button" value="開始" onclick="btn_start()"/> 8 <p id="num"></p> 9 <p id="result"></p> 10 <script> 11 'use strict'; 12 var sum; 13 function getRandomArbitrary(max) { 14 return Math.floor(Math.random() * (max - 1) + 1); 15 } 16 function calc(){ 17 var temp = getRandomArbitrary(10); 18 document.getElementById("num").innerHTML = temp; 19 sum += temp; 20 } 21 22 function btn_start(){ 23 sum = 0; 24 // 1.2秒のインターバルで繰り返し 25 let timerId = setInterval(() => calc(), 1200); 26 document.getElementById("result").innerHTML = sum; 27 // 4.8秒後に停止 28 setTimeout(() => { clearInterval(timerId); }, 4800); 29 } 30 </script> 31</body>

Javascript初心者です。よろしくお願い致します。

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

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

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

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

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

guest

回答3

0

calc()のなかでグローバル変数のsumに対して数値を追加しているが、0のまま。

ちゃんと足されてはいます。問題は、ocument.getElementById("result").innerHTML = sum;真っ先(1度目のcalcすら動かないうち)に実行されてしまうことかと思います。

投稿2020/04/08 02:22

maisumakun

総合スコア145183

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

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

kaitouEx

2020/04/08 08:00

実験してみて、本当にそのようになっていました。 ありがとうございます。とても勉強になりました。
guest

0

ベストアンサー

開始ボタンを押した瞬間に数字が表示されてよいですか?
合計値も4つ表示したあとに1.2秒まって表示でよいですか?

投稿2020/04/08 02:34

yambejp

総合スコア114767

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

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

yambejp

2020/04/08 02:43 編集

<script> window.addEventListener('DOMContentLoaded', ()=>{ var timerId=null; document.querySelector('#btn').addEventListener('click',async e=>{ e.target.disabled=true; var i=0; var sum=0; var v=0; var max=10; const speed=1200; var view=document.querySelector('#view'); while(i<4){ i++; v=1+Math.floor(Math.random()*max); sum+=v; view.textContent+="+"+v; await new Promise(resolve=>setTimeout(()=>resolve(),speed)); } view.textContent+="="+sum+" "; e.target.disabled=false; }); }); </script> <input type="button" value="開始" id="btn"> <div id="view"></div>
kaitouEx

2020/04/08 06:58

ありがとうございます。質問に回答いたします。 開始ボタンを押してから1.2秒待って、数字を表示したいです。 その場合は単純にwhile(i<4){ の行の上に await new Promise(resolve=>setTimeout(()=>resolve(),speed)); を配置するのでOKでしょうか。 合計値の表示は、4つ表示したあとに1.2秒まって表示で、合っています。 e.target.disabled=true;の、処理実行中はボタンを押せなくする処理も必要でしたね。盲点でした、ありがとうございます!また、最初このようなループ文でコードを書いていたのですが1.2秒待って実施する方法がわからず、非同期処理でかくのですね。そちらも勉強になりました。
yambejp

2020/04/08 07:01

最初1.2秒待つならpromiseを前に持ってくるだけですね そうすると合計を待たなくなるので、合計表示の前にもう一度 waitをかけます window.addEventListener('DOMContentLoaded', ()=>{ var timerId=null; document.querySelector('#btn').addEventListener('click',async e=>{ e.target.disabled=true; var i=0; var sum=0; var v=0; var max=10; const speed=1200; var view=document.querySelector('#view'); while(i<4){ i++; v=1+Math.floor(Math.random()*max); sum+=v; await new Promise(resolve=>setTimeout(()=>resolve(),speed)); view.textContent+="+"+v; } await new Promise(resolve=>setTimeout(()=>resolve(),speed)); view.textContent+="="+sum+" "; e.target.disabled=false; }); });
kaitouEx

2020/04/08 08:05

ありがとうございます。 4つの数字が切り替わるタイミングで一旦古い数字を消し、切れ目を見せるようにするため、 await new Promise(resolve=>setTimeout(()=>resolve(),speed)); view.textContent=""; await new Promise(resolve=>setTimeout(()=>resolve(),100));として と追加してうまく動かすことができました。 今回、こちらのコードが編集しやすく使い勝手が良かったので、こちらをベストアンサーにさせていただきます。 本当にありがとうございました。
guest

0

js

1function btn_start(){ 2 sum = 0; 3 // 1.2秒のインターバルで繰り返し 4 let timerId = setInterval(calc, 1200); // 関数calcをそのまま渡せばよいです 5 // 4.8秒後に停止 6 setTimeout(() => { 7 document.getElementById("result").innerHTML = sum; // 終了時に処理しないと 0 のままです 8 clearInterval(timerId); 9 }, 4800); 10} 11```**動くサンプル:**[https://jsfiddle.net/akcvjtoL/](https://jsfiddle.net/akcvjtoL/)

投稿2020/04/08 02:26

kei344

総合スコア69398

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

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

kaitouEx

2020/04/08 07:17

なるほど、setInterval()の中にcalcの戻り値を持たせるのではなくて setTimeout()の処理のなかで要素に値を持たせればよかったのですね。 サンプルもつけていただき、とてもわかりやすく勉強になりました!ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問