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

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

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

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

Q&A

解決済

2回答

909閲覧

JavaScript forとsetTimeoutと配列を組み合わせた謎の挙動について

uyyuuyuyuy

総合スコア7

JavaScript

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

0グッド

0クリップ

投稿2023/01/24 00:15

id="a"、b、cが最終的に全てleft:90%になるプログラムです
最終的に全てleft:90%になりません
原因がわからずにいます

setTimeoutを呼び出した時点でdocument.getElementById(i[n])のi[n]の中身は呼び出し時点の配列の中身で登録されていると思うのですが、違うんでしょうか

原因がわかる方教えてください

<script> window.onload=function(){ i=["a","b","c"]; x=["10","50","90"]; for(let n=0;n<i.length;n++){ for(let j=0;j<x.length;j++){ setTimeout(function(){ document.getElementById(i[n]).style.left=x[j]+"%"; },1000*Math.floor(Math.random()*5)); } } } </script> <div id="a" style="width:100px;height:100px;background:red;position:absolute;left:0%"> </div> <div id="b" style="width:100px;height:100px;background:green;position:absolute;left:0%"> </div> <div id="c" style="width:100px;height:100px;background:blue;position:absolute;left:0%"> </div>

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

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

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

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

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

dameo

2023/01/24 01:20 編集

多分0%→乱数時間空けて→10%→乱数時間空けて→50%→乱数時間空けて→90%としたいのでしょうけど、現状では 0%→乱数時間空けて→10% 0%→乱数時間空けて→50% 0%→乱数時間空けて→90% が平行で動いているため、最初の乱数時間よりも後ろ2つの乱数時間が短ければ先に90%や50%になってしまい、順番が狂ってしまいます。平行で動かさないためには、10%や50%にした「後」に「さらに待つ処理を入れ」ないawaitやPromiseを使わずに簡単に書くとこんな感じかと思います。 <script> window.onload = function() { i = ["a", "b", "c"]; x = ["0", "10", "50", "90"]; const f = function(i_idx, x_idx) { document.getElementById(i[i_idx]).style.left = x[x_idx] + "%"; if (++x_idx < x.length) { setTimeout(f, 1000 * Math.floor(Math.random() * 5), i_idx, x_idx); } } for(let n = 0; n < i.length; n++) { f(n, 0); } } </script> <div id="a" style="width:100px;height:100px;background:red;position:absolute;left:0%"> </div> <div id="b" style="width:100px;height:100px;background:green;position:absolute;left:0%"> </div> <div id="c" style="width:100px;height:100px;background:blue;position:absolute;left:0%"> </div>
guest

回答2

0

こういうことでしょうか?

javascript

1window.addEventListener('DOMContentLoaded', async()=>{ 2 i=["a","b","c"]; 3 x=["10","50","90"]; 4 for(let n=0;n<i.length;n++){ 5 for(let j=0;j<x.length;j++){ 6 await new Promise(resolve=>{ 7 setTimeout(()=>{ 8 document.getElementById(i[n]).style.left=x[j]+"%"; 9 resolve(); 10 },100*Math.floor(Math.random()*5)); 11 }); 12 } 13 } 14});

投稿2023/01/24 00:37

yambejp

総合スコア114779

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

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

0

ベストアンサー

配列 x の各項目が順番に関係なく乱数秒後にleftプロパティにセットされるので、j2 のときの乱数が一番大きかったときだけ最終的に90%になります。setTimeout()は予約をするだけで即座に返ってくることがポイントです。

やりたいことがいまいちはっきりしませんが、「乱数 * 5 秒後に90%にしたい」ということでしょうか。

js

1for (let n = 0; n < i.length; n++) { 2 let finishDuration = 1000*Math.floor(Math.random() * 5); 3 for (let j = 0; j < x.length; j++) { 4 setTimeout(function(){ 5 document.getElementById(i[n]).style.left = x[j] + "%"; 6 }, finishDuration * (j + 1) / x.length); 7 } 8}

js

1 for (let n = 0; n < i.length; n++) { 2 let finishDuration = 1000 * Math.floor(Math.random() * 5); 3 document.getElementById(i[n]).animate( 4 [{left: '0%'}, {left: '90%'}], {duration:finishDuration, fill:'forwards'}); 5 }

「乱数 * 5 秒後に10%、その乱数 * 5 秒後に50%、その乱数 * 5 秒後に90%」であれば:

js

1for (let n = 0; n < i.length; n++) { 2 let duration = 0; 3 for (let j = 0; j < x.length; j++) { 4 duration += 1000 * Math.floor(Math.random() * 5); 5 setTimeout(function(){ 6 document.getElementById(i[n]).style.left = x[j] + "%"; 7 }, duration); 8 } 9}

3つの要素も(並列ではなく)順番に動かしたいなら:

js

1let duration = 0; 2for (let n = 0; n < i.length; n++) { 3 for (let j = 0; j < x.length; j++) { 4 duration += 1000 * Math.floor(Math.random() * 5); 5 setTimeout(function(){ 6 document.getElementById(i[n]).style.left = x[j] + "%"; 7 }, duration); 8 } 9}

投稿2023/01/24 00:26

編集2023/01/24 01:28
int32_t

総合スコア20845

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問