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

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

新規登録して質問してみよう
ただいま回答率
85.48%
イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

JavaScript

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

Q&A

0回答

909閲覧

javascript イベントハンドラに登録されたタイマーの多重発動防止

sora_5656

総合スコア0

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

JavaScript

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

0グッド

0クリップ

投稿2021/03/28 16:23

前提・実現したいこと

現在オセロを作成していて、白と黒の互いのタイマーを作成したいです.

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

開いているマスに石を置くと、タイマーが発動するようになり、turnの偶奇ごとにそれぞれのカウントが減っていく仕様にしております。しかし、石を3回目以降に置くと(それぞれの石の2回目以降)、
本来は1秒分減らしたいところ、置いた数×秒数分だけ、カウントが減ってしまいます。(イベントハンドラが何重にも発動しているからだと思われます).

該当のソースコード

javascript

1function put() { 2 for (let x = 1; x <= 8; x++) { 3 for (let y = 1; y <= 8; y++) { 4 var position = conversion(x, y); 5 addListener(document.getElementById(position), 'click', subPut); 6 } // 7 } // 8} 9 10 11function subPut(e) { 12 let position = getID(this); 13 let xy = inverseConversion(position); 14 x = xy[0]; 15 y = xy[1]; 16 x = parseInt(x); 17<--------------------------------------------------------------------------- 18 if (turn > 1) { 19 console.log("preposition: " + preposition); 20 console.log("preevent: " + preevent); 21 preevent.preventDefault(); // 22 23 } 24 console.log("position: " + position); 25 preposition = position; 26 preevent = e; 27----------------------------------------------------------------------------> 28 let count = 0; 29 if (board[x][y] == EMPTY) { 30 for (let i = -1; i <= 1; i++) { 31 for (let j = -1; j <= 1; j++) { 32 if (i == 0 && j == 0) { 33 continue; 34 } else if (board[x + i][y + j] == (turn + 1) % 2) { //隣り合う石が違う色 35 let s = 1; 36 while (board[x + s * i][y + s * j] == (turn + 1) % 2) { 37 s++; 38 } 39 if (board[x + s * i][y + s * j] == (turn) % 2) { //先端が自分の色 40 for (let t = 1; t < s; t++) { 41 board[x + t * i][y + t * j] = (turn) % 2; 42 count++; 43 } 44 } else { 45 continue; 46 } 47 48 } else { 49 continue; 50 } 51 } //j 52 } //i 53 if (count) { 54 realPut(); 55 } else { 56 window.alert("挟める石がないので、置き直してください"); 57 } 58 } //その場所が開いている場合 59} //関数終わり 60 61function realPut() { 62 63 var w_timer; 64 var b_timer; 65 66 var w_time; 67 68 var b_time; 69 console.log("turn" + turn); 70 board[x][y] = turn % 2; 71 changeBoard(); 72 73 // 74 75 76 77<-------------------------------------------------------------------------------- 78 79 b_timer = window.setInterval( 80 function() { 81 if (turn % 2 == BLACK) { 82 b_second_time--; 83 } 84 if (b_second_time % 60 < 10) { 85 b_time = Math.floor(b_second_time / 60) + ":0" + b_second_time % 60; 86 } else { 87 b_time = Math.floor(b_second_time / 60) + ":" + b_second_time % 60; 88 } 89 document.getElementById('b.time').innerHTML = b_time; 90 }, 1000); 91 92 w_timer = window.setInterval( 93 function() { 94 if (turn % 2 == WHITE) { 95 w_second_time--; 96 } 97 if (w_second_time % 60 < 10) { 98 w_time = Math.floor(w_second_time / 60) + ":0" + w_second_time % 60; 99 } else { 100 w_time = Math.floor(w_second_time / 60) + ":" + w_second_time % 60; 101 } 102 document.getElementById('w.time').innerHTML = w_time; 103 }, 1000); 104-------------------------------------------------------------------------------> 105 turn++; 106 107 countPut(); 108 if (flag == 1) { 109 countPut(); 110 } 111 112 113} 114 115 116

試したこと

石が置き終わったイベントハンドラの削除やそのイベントをpreventDefalutさせたり、clearintervalなども試みてみました
このコードでは、preventDefalutさせたみたものを載せております。

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

<-- --> で囲まれたところがタイマー作成の該当箇所となります.(2箇所)
まだ未熟で、分かりづらいコード、文章で大変申し訳ございませんが、ご教示をお願い致します。

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

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

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

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

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

babu_babu_baboo

2021/03/28 23:44

変数 b_timer と w_timer を外に出す(グローバル変数にする) 関数 realPut が呼び出されたら、clearInterval を使ってタイマーを解除する -- アドバイス 関数1つで完結するのではなく、細分化して共通に使えそうなものを呼び出すようにする。
yambejp

2021/03/29 00:26

addListenerの定義が見当たりません
sora_5656

2021/03/29 10:24

@babu_babu_baboo timerを外に出したらうまくいきました。 ご教示本当にありがとうございました。 アドバイスの方も参考にさせて頂きます。
sora_5656

2021/03/29 10:26

@yambejp 申し訳ございません。次回からの質問の際に関数や変数の定義の記入漏れに気を付けたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問