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

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

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

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

Q&A

2回答

2577閲覧

js非同期処理を同期処理にしたい

Luu-chann

総合スコア0

JavaScript

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

0グッド

0クリップ

投稿2021/05/24 06:54

編集2022/01/12 10:55

前提・実現したいこと

イメージ説明
現在、プログラミングを勉強し始めたところです。
そこでじゃんけんゲームを作っています。
jsを使っています。

実現したいことは
function come_handの関数を、順番通りに起動させたいです。
td2というHTMLの文章内にアクセスして、
そこにb.innerHTMLで定義しているものを持って行ってから
じゃんけんの結果をだしたいです。

発生している問題・エラーメッセージ

しかし、現在のコードでは
じゃんけんの結果がアラートで表示されてから
b.innderHTMLが表示されるになっています。

##HTML&javascript

<html lang="ja"> <!--~の(要素)、~は(属性)、~です(属性値)--> <head> <meta charset="utf-8"> <title>じゃんけんげーむ</title> <meta name="utf-8"> <link href="stylesheet.css" rel="stylesheet"> </head> <body> <!--うぇぶページぽくヘッダーを作るべし--> <header class="header"> <div class="beako"> <img src="img/beako.png" class="img_beako"> <p>じゃんけんするのよ!</p> <h3 style="text-align:right;">すばるの下にあるボタン推してみるのよ!</h3> </div> <nav class="nav"> <ul> <li><a href="file:///C:/Users/81804/OneDrive/%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97/%E7%B7%B4%E7%BF%92%E3%81%AA%E3%81%AE%EF%BD%9E%EF%BD%9E%EF%BD%9E/%E3%82%8B%E3%83%BC%E3%81%A1%E3%82%83%E3%82%93.html">るーちゃん</a></li> <li><a href="file:///C:/Users/81804/OneDrive/%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97/%E7%B7%B4%E7%BF%92%E3%81%AA%E3%81%AE%EF%BD%9E%EF%BD%9E%EF%BD%9E/%E3%81%8A%E3%81%97%E3%81%A6%E3%81%BF%EF%BC%9F.html">おしてみ?</a></li> <li><a href="#">えへへ</a></li> </ul> </nav> </header> <table class="table"> <tr> <td id="td1"></td> <td id="td2"></td> </tr> <tr> <td> <img src="img/ekidona.png" class="ekidona" width="300px" height="270px"> </td> <td id="subaru"> <img src="img/subaru.png" width="250px" height="270px"> </td> </tr> <tr> <td colspan="3" id="col"> <input type="button" value="ぐ~" id="myHand" onclick="come_hand(1)"> <input type="button" value="ちょき" id="myHand" onclick="come_hand(0)"> <input type="button" value="ぱー" id="myHand" onclick="come_hand(2)"> </td> </tr> </table> </div> </body> <script src="javascript2.js"></script> </html> ----------------------- var value=prompt("呼ばれたい名前を入力するかしらっ、、、!"); //まずは、じゃんけんの手を数値化させてあげる// var images = new Array ("img/choki.png","img/guu.png","img/paa.png"); console.log(images[1]); //数値化させた手をランダムで取るように&整数で表示// //window.setInterval(getPC_hand,100);// var random = 9; function getPC_hand(){ var a = document.getElementById("td1"); random = Math.floor(Math.random() *3); a.innerHTML= "<img src ='"+images[random]+"' id='PC' width='150px:'>"; window.setTimeout(getPC_hand,100); } getPC_hand(); /*①HTMLで動かしたい関数を書く  ②渡したい値(引数)を書いててもいい~  ③関数()←引数が入る箱  ④渡された引数を使いたい場所に箱の名前をおいてあげる*/ function come_hand(myHand){ var b = document.getElementById("td2"); b.innerHTML= "<img src ='"+images[myHand]+"' id='PC' width='150px:'>"; if (myHand === random){ window.alert("あいこ!!"+value+"もっかいやる?"); } //勝ちの判定   if (myHand === 1 && random === 0){ window.alert ("勝ちい~~!"+value+"おめでとう~(*´ω`)"); } if (myHand === 2 && random ===1){ window.alert ("勝ちい~~!"+value+"おめでとう~(*´ω`)"); } if (myHand === 0 && random ===2){ window.alert ("勝ちい~~!"+value+"おめでとう~(*´ω`)"); } //負け判定 if (myHand === 1 && random ===2){ window.alert (""+value+"の負けえ。。。残念(´;ω;`)"); } if (myHand === 2 && random ===0){ window.alert (""+value+"の負けえ。。。残念(´;ω;`)"); } if (myHand === 0 && random ===1){ window.alert (""+value+"の負けえ。。。残念(´;ω;`)"); } }

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

多分、同期比同期の話の問題だと思うのですが
助言いただけると嬉しいです。
イメージ説明

ボタンを押すと、先に結果が表示され
おkを押すと、手の表示がされます。

イメージ説明
これを、ボタンを押すと手の画像が表示されて
アラートで結果が出る。という動作にしたいです

javascript

1//var value=prompt("呼ばれたい名前を入力するかしらっ、、、!");// 2 3//まずは、じゃんけんの手を数値化させてあげる// 4var images = new Array ("img/choki.png","img/guu.png","img/paa.png"); 5console.log(images[1]); 6 7//数値化させた手をランダムで取るように&整数で表示// 8//window.setInterval(getPC_hand,100);// 9 10var random = 9; 11 12 13function getPC_hand(){ 14 var a = document.getElementById("td1"); 15 random = Math.floor(Math.random() *3); 16 a.innerHTML= "<img src ='"+images[random]+"' id='PC' width='150px:'>"; 17 window.setTimeout(getPC_hand,100); 18} 19 20getPC_hand(); 21 22 23var dialog = document.querySelector("dialog"); 24var btn_show = document.getElementById("myHand"); 25btn_show.addEventListener('click', function() { 26 dialog.show(); 27}, false); 28 29 30 31 function come_hand(myHand){ 32 var b = document.getElementById("td2"); 33 b.innerHTML= "<img src ='"+images[myHand]+"' id='PC' width='150px:'>"; 34}; 35 36function come_hand(myHand){ 37 var b = document.getElementById("modal"); 38 if (myHand === random){ 39 window.alert("あいこ!!"+value+"もっかいやる?"); 40 } 41 //勝ちの判定 42   if (myHand === 1 && random === 0){ 43 window.alert ("勝ちい~~!"+value+"おめでとう~(*´ω`)"); 44 } 45 if (myHand === 2 && random ===1){ 46 window.alert ("勝ちい~~!"+value+"おめでとう~(*´ω`)"); 47 } 48 if (myHand === 0 && random ===2){ 49 window.alert ("勝ちい~~!"+value+"おめでとう~(*´ω`)"); 50 } 51 //負け判定 52 if (myHand === 1 && random ===2){ 53 window.alert (""+value+"の負けえ。。。残念(´;ω;`)"); 54 } 55 if (myHand === 2 && random ===0){ 56 window.alert (""+value+"の負けえ。。。残念(´;ω;`)"); 57 } 58 if (myHand === 0 && random ===1){ 59 window.alert (""+value+"の負けえ。。。残念(´;ω;`)"); 60 } 61} 62 63 64/*①HTMLで動かしたい関数を書く 65 ②渡したい値(引数)を書いててもいい~ 66 ③関数()←引数が入る箱 67 ④渡された引数を使いたい場所に箱の名前をおいてあげる*/ 68

HTML

1<html lang="ja"> 2 <!--~の(要素)、~は(属性)、~です(属性値)--> 3<head> 4 <meta charset="utf-8"> 5 <title>じゃんけんげーむ</title> 6 <meta name="utf-8"> 7 <link href="stylesheet.css" rel="stylesheet"> 8</head> 9 10<body> 11 12<!--うぇぶページぽくヘッダーを作るべし--> 13<header class="header"> 14 15 <div class="beako"> 16 <img src="img/beako.png" class="img_beako"> 17 <p>じゃんけんするのよ!</p> 18 <h3 style="text-align:right;">すばるの下にあるボタン推してみるのよ!</h3> 19 </div> 20 21 <nav class="nav"> 22 <ul> 23 <li><a href="file:///C:/Users/81804/OneDrive/%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97/%E7%B7%B4%E7%BF%92%E3%81%AA%E3%81%AE%EF%BD%9E%EF%BD%9E%EF%BD%9E/%E3%82%8B%E3%83%BC%E3%81%A1%E3%82%83%E3%82%93.html">るーちゃん</a></li> 24 <li><a href="file:///C:/Users/81804/OneDrive/%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97/%E7%B7%B4%E7%BF%92%E3%81%AA%E3%81%AE%EF%BD%9E%EF%BD%9E%EF%BD%9E/%E3%81%8A%E3%81%97%E3%81%A6%E3%81%BF%EF%BC%9F.html">おしてみ?</a></li> 25 <li><a href="#">えへへ</a></li> 26 </ul> 27 </nav> 28 29 30</header> 31 32<table class="table"> 33 <tr> 34 <td id="td1"></td> 35 <td id="td2"></td> 36 </tr> 37 38 <tr> 39 <td> 40 <img src="img/ekidona.png" class="ekidona" width="300px" height="270px"> 41 </td> 42 <td id="subaru"> 43 <img src="img/subaru.png" width="250px" height="270px"> 44 </td> 45 </tr> 46 47 <tr> 48 49<!--モーダルダイアログ--> 50<dialog> 51 <p id="modal"></p> 52</dialog> 53 54 <td colspan="3" id="col"> 55 <input type="button" value="ぐ~" id="myHand" onclick="come_hand(1)"> 56 <input type="button" value="ちょき" id="myHand" onclick="come_hand(0)"> 57 <input type="button" value="ぱー" id="myHand" onclick="come_hand(2)"> 58 </td> 59 </tr> 60</table> 61</div> 62 63</body> 64 <script src="javascript2.js"></script> 65</html> 66 67

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

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

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

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

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

guest

回答2

0

質問の様にjavascriptでimgのsrc属性を変更して画像を変える場合、画像の変更(既存の画像を破棄し、srcのurlから画像をloadし、画面に表示する)は非同期に実行されます。
対してalert関数は処理の同期非同期関係なく、今ウィンドウで動いている処理を全て停止させてダイアログを表示させます。状況に関係なく割り込んでくるんですね。

画像が完全に表示されてからalertが出ると良いわけですが、imgが完全にloadされて、画面に表示されたかどうかを直接イベントなどで捕まえる術がありません。imgにはloadイベントがありますが、これは画像データのダウンロードが完了した時点で呼ばれるものであり、画面への描画が完了した際に呼ばれるわけではありません。なのでloadイベント中にalertを出しても画像が変更されてないことが多々あります。

解決策として、私は2通り考えます。

  1. alertを使わない。

別の手段でモーダルダイアログを表示させる方法です。モーダルダイアログを表示するライブラリはbootstrapをはじめ数多く存在するので好きなライブラリを使ってよいと思います。
基本的にこの方法はモーダルのHTML要素をメイン画面にかぶせるだけなので、ブロッキングが発生しません。

  1. Intersection Observer API を使う

ターゲットの要素が画面に表示されかかったかどうかを検知できる仕組みがあります。

  • じゃんけんの手は都度srcを変更する方法ではなく、それぞれの画像を先に用意しておきdisplay:noneしておく
  • 選択した手に応じた画像に対してdisplay:noneを外す
  • 選択した画像が表示される
  • Intersection Observer API が「画面に画像が表示されかかった」ことを検知し、指定したコールバック関数が実行される
  • コールバック関数の中にalert関数を書いておく

という手順を踏むことで、画像が表示されてからalertを出すことが可能です。
ただし画像が変更されない場合は交差状態の変化も検知されないので、じゃんけん前に画像を消去状態にしておくなどの対策が必要です。

2.は実装が難しいので1.の方法で実装することをお勧めします。

一応、2.の方法で実装したデモ

投稿2021/05/24 08:13

hope_mucci

総合スコア4447

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

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

Luu-chann

2021/05/26 05:08

ご回答ありがとうございます!! 実装1について調べてみたのですが なかなか進まなくて。 ダイアログ要素を使って モーダルダイアログを出現させることはできたのですが 出現させた内容をじゃんけん結果に表記させることコーディングは わかりません。 やりたいことは 1.ぐー・ちょき・ぱーのボタンにアクセス 2.ボタンを押すと、じゃんけん結果を読み取る 3.その結果をダイアログで表示 4.ダイアログ内で閉じるボタンを作成 少しアドバイスいただいてもいいでしょうか、、? 図々しくてすみません。 書き加えたコードは、質問画面に加えておきます。 よろしくお願いいたします。
hope_mucci

2021/05/26 09:42 編集

dialog要素をつかおうとしているのですね。 簡単な実装例がmozillaのドキュメントに載っていますが、これはformの中で扱う例です。 https://developer.mozilla.org/ja/docs/Web/HTML/Element/dialog 単純な例は以下のサイトのサンプルがシンプルなので参考になるかと思います。 https://reference.hyper-text.org/html5/element/dialog/ 提示のコードで表現するのであれば、 - dialog要素中のp要素('#modal')にalert版で表示していたメッセージをセットする - dialog要素に対してshowModal()関数を実行 と言うように実装を変更すれば最低限メッセージの表示はできるようになるでしょう。
Luu-chann

2021/06/03 13:30

質問答えてもらってありがとうございます(´;ω;`) ただ、、、あれ以来毎日いじってはいるのですが なかなかできなくて できたので、ありがとうございますの報告ができず 無視しているような形になってすみません、、、 もう少し自分なりに頑張ってみますので すみません、、、
hope_mucci

2021/06/03 16:46

出来ないのであればモーダルダイアログはあきらめてもいいのではないですか。 真ん中の空いている部分に「勝ち」とか「負け」を表示する方法でも良いのでは。 モーダルダイアログの実装は意外と難しいです。javascirptの非同期処理についてちゃんと理解していないと適切に実装できません。再学習してからまたトライしても良いのではないでしょうか。
guest

0

setTimeoutを同期処理で対応したいならPromiseとasync/awaitで処理するのでしょうけど
ちょっと質問が散らかりすぎているので、もう少しピンポイントに問題点を
まとめたほうが良いと思います

投稿2021/05/24 06:58

yambejp

総合スコア114572

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

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

Luu-chann

2021/05/24 07:12

すみません。 補足情報の部分に付け加えました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問