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

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

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

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

Q&A

解決済

3回答

347閲覧

関数の定義と呼び出しの記述について

narururu

総合スコア172

JavaScript

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

0グッド

0クリップ

投稿2017/12/01 11:13

編集2017/12/01 16:20

###実現したいこと
スタートボタンを押すとpairsで定義した全ての枚数のカードが裏返しになる。

###現状
スタートボタンを押しても何も変化なし。

###ソースコード
html

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Memory Game</title> <link rel="stylesheet" href="css/styles.css"> </head> <body> <div class="container"> <div id="score">0.00</div> <div id="stage"> <!-- <div class="card-container"> <div class="card"> <div class="card-front">1</div> <div class="card-back">?</div> </div> </div> --> </div> <div id="btn">スタート</div> </div> <script src="js/main.js"></script> </body> </html>

css

body { background: #3498db; font-family: Arial, sans-serif; font-size: 16px; font-weight: bold; } .container { width: 360px; margin: 20px auto; } #stage { display: flex; flex-wrap: wrap; } .card-container { perspective: 100px; width: 50px; height: 70px; margin: 5px; } .card { cursor: pointer; width: 100%; height: 100%; transition: 0.8s; position: relative; transform-style: preserve-3d; } .card-front, .card-back { width: 100%; height: 100%; text-align: center; line-height: 70px; border-radius: 8px; position: absolute; top: 0; left: 0; backface-visibility: hidden; box-shadow: 0 5px 0 rgba(0, 0, 0, 0.2); } .card-back { background: #f1c40f; color: #fff; } .card-back:hover { opacity: 0.8; } .card-front { background: #fff; color: #f1c40f; transform: rotateY(180deg); } .card.open { transform: rotateY(180deg); } .container div { display: inline-block; } .container p { font-size: 20px; color: #fff; text-align: left; margin: 0 5px 10px 0; width: 150px: } #score { font-size: 20px; color: #fff; text-align: right; margin: 0 5px 10px 0; width: 150px: } #btn { background: gray; color: #fff; height: 40px; border-radius: 20px; line-height: 40px; text-align: center; font-size: 18px; margin: 15px auto 0; box-shadow: 0 5px 0 rgba(0, 0, 0, 0.2); width: 300px; cursor: pointer; }

js

(function() { 'use strict'; var pairs = 2; var cards = []; var flipCount = 0; var firstCard = null; var secondCard = null; var startTime; var isRunning = false; var correctCount = 0; var timeoutId; function init() { var i; var card; for (i = 1; i <= pairs; i++) { cards.push(createCard(i)); cards.push(createCard(i)); // document.getElementById('stage').appendChild(createCard(i)); // document.getElementById('stage').appendChild(createCard(i)); } while (cards.length) { card = cards.splice(Math.floor(Math.random() * cards.length), 1)[0]; document.getElementById('stage').appendChild(card); } } function createCard(num) { var container; var card; var inner; inner = '<div class="card-front">' + num + '</div><div class="card-back">?</div>'; card = document.createElement('div'); card.innerHTML = inner; card.className = 'card'; card.addEventListener('click', function() { flipCard(this); if (isRunning === true) { return; } isRunning = true; startTime = Date.now(); runTimer(); document.getElementById('restart').className = ''; }); container = document.createElement('div'); container.className = 'card-container'; container.appendChild(card); return container; } function flipCard(card) { if (firstCard !== null && secondCard !== null) { return; } if (card.className.indexOf('open') !== -1) { return; } card.className = 'card open'; flipCount++; if (flipCount % 2 === 1) { firstCard = card; } else { secondCard = card; secondCard.addEventListener('transitionend', check); } } function check() { if ( firstCard.children[0].textContent !== secondCard.children[0].textContent ) { firstCard.className = 'card'; secondCard.className = 'card'; } else { correctCount++; if (correctCount === pairs) { clearTimeout(timeoutId); } } secondCard.removeEventListener('transitionend', check); firstCard = null; secondCard = null; } function runTimer() { document.getElementById('score').textContent = ((Date.now() - startTime) / 1000).toFixed(2); timeoutId = setTimeout(function() { runTimer(); }, 10); } init(); })(); //ここのコードです function startBtn(btn) { btn.addEventListener("click", function(){ card.className = "card open"; }); } startBtn(); //ここまで

どなたか、ご回答よろしくお願いいたします。

###追記
エラーメッセージは以下の通りです。画面をキャプチャしました。
ご確認お願いいたします。
https://i.gyazo.com/ad85ab2371a0e99421607a1d49f94c02.png
https://i.gyazo.com/ca8988669dc4ff155ec34705ed36eb45.png

皆様、本当にご丁寧なアドバイスありがとうございました。
皆様にベストアンサーを差し上げたいところですが、今回は実現したい内容をコードとして提示してくださった方をベストアンサーとさせていただきます。
本当にありがとうございました(>_<)

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

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

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

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

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

defghi1977

2017/12/01 11:24

少なくともエラーを吐いているはずなので, まずはどのようなエラーか確認して下さい
guest

回答3

0

プログラムを学ぶ上でエラーの内容を理解することは重要です. 大抵は英語で出力されるためとっつきにくいかもしれませんが, 内容そのものはさほど難しくない(中学英語で十分理解できる範囲)ですので頑張って下さい.


さて, エラーが発生している原因ですがエラーメッセージのとおりです. つまり
"Can not read property 'addEventListener' of undefined"
訳すと
undefinedのプロパティaddEventListenerを読み込むことが出来ません」
です.

で, なぜこのようなエラーが発生しているのかというと当該コードにおいて,

JavaScript

1//ここのコードです 2function startBtn(btn) { 3 btn.addEventListener("click", function(){ 4 card.className = "card open"; 5 }); 6} 7startBtn();//←??? 8//ここまで

関数startBtnを定義した後, 呼び出し時の引数として何も渡していません. これをJavaScriptでは**「undefinedが渡された」**と解釈します. (「りんごがない」を「りんごが0個ある」と言い換えるのと同じです.)

従って関数startBtn定義部の引数であるbtn変数にはundefinedが渡されます. ここでundefined何もないことを表す定数ですから, そこにaddEventListenerメソッドは存在しません. にもかかわらず, あなたはaddEventListenerメソッドを呼び出そうとしました.

このことで先ほどのエラー"Can not read property 'addEventListener' of undefined"が発生したのです.

つまり, この問題は関数startBtnaddEventListenerメソッドをもつ何かを渡せばよかったのです.

そうすると次には「addEventListenerメソッドをもつ何か」とは何だろうとなります. そこでs8_chuさんが提示したようなコードが現れるのです.

JavaScript

1//ここのコードです 2function startBtn(btn) { 3 btn.addEventListener("click", function(){ 4 card.className = "card open"; 5 }); 6} 7startBtn(document.getElementById("btn"));//←ここにボタンを渡している 8//ここまで

しかし、頂いたコードでは、スタートボタンをクリックしても全てのカードが裏返しになることはありませんでした。

少なくともこれで, エラーは一つ解決しました. ですから今度はあなたが動かない原因をもう一度見つけ, それが解決できないのであれば改めて質問されると良いでしょう.

プログラムを行う上で大事なことは, いつも小さなコードを作ってそれが正しく動くことを確認していき, それを集めて大きなプロダクトにしていくことです. ですから, 今回あなたが提示したように「大きなコード」を動かないからと言ってそのまままるごと「動きません。なぜですか?」と言われても, 答える側としては, 「それは問題の切り分けが出来ていないあなたの責任」といったように見えてしまっているのです.

勿論、これ以上回答を依頼することはしません。私自身で考え問題解決するよう努めさせていただきます。

むしろ, 積極的に質問して下さい. もちろん何がわからないのか・どこに詰まっているかが判るように「必要最低限のコードで」という条件付きではありますが, 答えやすい問であれば皆さん快く回答してくださるはずです.

投稿2017/12/01 15:53

defghi1977

総合スコア4756

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

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

narururu

2017/12/01 16:11

ご回答ありがとうございます。 今回の質問は私自身で考えず、答えだけを求めている内容になってしまいました。コード量も多く、質問する側がきちんと把握できていない証拠です。 今後は、回答者様が答えやすい問いになるように、エラーメッセージから自分で考え検証するというプロセスを経て、質問していきます。 ご丁寧なアドバイスありがとうございます。
guest

0

ベストアンサー

質問者さんが実現したいことは以下のようにすることで行えると思います。

HTML

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="utf-8"> 5 <title>Memory Game</title> 6 <style type="text/css"> 7 body { 8 background: #3498db; 9 font-family: Arial, sans-serif; 10 font-size: 16px; 11 font-weight: bold; 12 } 13 14 .container { 15 width: 360px; 16 margin: 20px auto; 17 } 18 19 #stage { 20 display: flex; 21 flex-wrap: wrap; 22 } 23 24 .card-container { 25 perspective: 100px; 26 width: 50px; 27 height: 70px; 28 margin: 5px; 29 } 30 31 .card { 32 cursor: pointer; 33 width: 100%; 34 height: 100%; 35 transition: 0.8s; 36 position: relative; 37 transform-style: preserve-3d; 38 } 39 40 .card-front, 41 .card-back { 42 width: 100%; 43 height: 100%; 44 text-align: center; 45 line-height: 70px; 46 border-radius: 8px; 47 position: absolute; 48 top: 0; 49 left: 0; 50 backface-visibility: hidden; 51 box-shadow: 0 5px 0 rgba(0, 0, 0, 0.2); 52 } 53 54 .card-back { 55 background: #f1c40f; 56 color: #fff; 57 } 58 59 .card-back:hover { 60 opacity: 0.8; 61 } 62 63 .card-front { 64 background: #fff; 65 color: #f1c40f; 66 transform: rotateY(180deg); 67 } 68 69 .card.open { 70 transform: rotateY(180deg); 71 } 72 73 .container div { 74 display: inline-block; 75 } 76 77 .container p { 78 font-size: 20px; 79 color: #fff; 80 text-align: left; 81 margin: 0 5px 10px 0; 82 width: 150px; /* コロンではなく、セミコロン */ 83 } 84 85 #score { 86 font-size: 20px; 87 color: #fff; 88 text-align: right; 89 margin: 0 5px 10px 0; 90 width: 150px; /* コロンではなく、セミコロン */ 91 } 92 93 #btn { 94 background: gray; 95 color: #fff; 96 height: 40px; 97 border-radius: 20px; 98 line-height: 40px; 99 text-align: center; 100 font-size: 18px; 101 margin: 15px auto 0; 102 box-shadow: 0 5px 0 rgba(0, 0, 0, 0.2); 103 width: 300px; 104 cursor: pointer; 105 } 106 107 .hidden { 108 display: none !important; 109 } 110 </style> 111</head> 112<body> 113<div class="container"> 114 <div id="score">0.00</div> 115 <div id="stage"> 116 <!-- <div class="card-container"> 117 <div class="card"> 118 <div class="card-front">1</div> 119 <div class="card-back">?</div> 120 </div> 121 </div> --> 122 </div> 123 <div id="btn">スタート</div> 124 <div id="restart" class="hidden">restart</div> 125</div> 126<script> 127 (function () { 128 'use strict'; 129 130 var pairs = 2; 131 var cards = []; 132 133 var flipCount = 0; 134 var firstCard = null; 135 var secondCard = null; 136 137 var startTime; 138 var isRunning = false; 139 var correctCount = 0; 140 var timeoutId; 141 142 143 function init() { 144 var i; 145 var card; 146 for (i = 1; i <= pairs; i++) { 147 cards.push(createCard(i)); 148 cards.push(createCard(i)); 149 150 // document.getElementById('stage').appendChild(createCard(i)); 151 // document.getElementById('stage').appendChild(createCard(i)); 152 } 153 154 while (cards.length) { 155 card = cards.splice(Math.floor(Math.random() * cards.length), 1)[0]; 156 document.getElementById('stage').appendChild(card); 157 } 158 } 159 160 161 function createCard(num) { 162 var container; 163 var card; 164 var inner; 165 inner = '<div class="card-front">' + num + '</div><div class="card-back">?</div>'; 166 card = document.createElement('div'); 167 card.innerHTML = inner; 168 card.className = 'card'; 169 card.addEventListener('click', function () { 170 flipCard(this); 171 if (isRunning === true) { 172 return; 173 } 174 isRunning = true; 175 startTime = Date.now(); 176 runTimer(); 177 document.getElementById('restart').className = ''; 178 }); 179 container = document.createElement('div'); 180 container.className = 'card-container'; 181 container.appendChild(card); 182 return container; 183 } 184 185 function flipCard(card) { 186 if (firstCard !== null && secondCard !== null) { 187 return; 188 } 189 if (card.className.indexOf('open') !== -1) { 190 return; 191 } 192 card.className = 'card open'; 193 card.querySelector(".card-back").style.zIndex = -1; 194 flipCount++; 195 if (flipCount % 2 === 1) { 196 firstCard = card; 197 } else { 198 secondCard = card; 199 secondCard.addEventListener('transitionend', check); 200 } 201 } 202 203 function check() { 204 if ( 205 firstCard.children[0].textContent !== 206 secondCard.children[0].textContent 207 ) { 208 firstCard.className = 'card'; 209 secondCard.className = 'card'; 210 } else { 211 correctCount++; 212 if (correctCount === pairs) { 213 clearTimeout(timeoutId); 214 } 215 } 216 secondCard.removeEventListener('transitionend', check); 217 firstCard = null; 218 secondCard = null; 219 } 220 221 function runTimer() { 222 document.getElementById('score').textContent = ((Date.now() - startTime) / 1000).toFixed(2); 223 timeoutId = setTimeout(function () { 224 runTimer(); 225 }, 10); 226 } 227 228 init(); 229 230 //ここのコードです 231 function startBtn(btn) { 232 233 btn.addEventListener("click", function () { 234 235 236 for (var i = 0, e = document.querySelectorAll(".card-container .card"); i < e.length; i++) { 237 e[i].className = "card open"; 238 e[i].querySelector(".card-back").style.zIndex = -1; 239 } 240 }); 241 } 242 243 startBtn(document.getElementById("btn")); 244 //ここまで 245 })(); 246</script> 247</body> 248</html>

投稿2017/12/01 14:43

編集2017/12/01 15:44
s8_chu

総合スコア14731

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

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

narururu

2017/12/01 15:07

ご回答ありがとうございます。 丸投げな質問に対し、ご丁寧にコードまで記述していただき恐縮です。 しかし、頂いたコードでは、スタートボタンをクリックしても全てのカードが裏返しになることはありませんでした。 勿論、これ以上回答を依頼することはしません。私自身で考え問題解決するよう努めさせていただきます。 貴重なアドバイス、ありがとうございました。
s8_chu

2017/12/01 15:56 編集

> 頂いたコードでは、スタートボタンをクリックしても全てのカードが裏返しになることはありませんでした。... 私自身で考え問題解決するよう努めさせていただきます。 念のため回答を修正しておきました。
narururu

2017/12/01 16:01

s8_chuさん、わざわざありがとうございます。 参考にさせていただきます。 いつもいつも、本当に助かります! このコードを基にいろいろ試してみます☺ 私はちゃんと勉強しないと(>_<)
guest

0

cardやbtnがつかめてないですね。
idを指定してオブジェクトをつかむ方式に
document.querySelector('#hoge')と
document.getElementById('hoge')があるので
そのあたりから学習されるとよいでしょう

投稿2017/12/01 11:49

yambejp

総合スコア114839

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

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

narururu

2017/12/01 12:03

ご回答ありがとうございます。 そうですね。 私はまず、きちんと学習することから始めます。 丸投げ質問にならないよう気を付けます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問