第7回 エディターが学ぶ初めてのプログラミング(JavaScript編 addEventListener)

あと何回で歯医者が終わるか待ち遠しい、エディター若栁です。
エディターが学ぶ初めてのプログラミング、第7回をお送りします。

HTMLのファイルを見直してみた

一通り前の回で、動作の不具合も直ったスロットゲームですが、自分で書いたHTMLのコードを改めて見たところ、

ボタンの動作を制御するJavaScriptのonclick属性が、HTMLの中に書かれていました。
別に動くからいいじゃーん。はい、動きます。ただ、HTML(構造)やJavaScript(動き)、CSS(見た目)とそれぞれ役割が違います。

これについてはセマンティックWebという考え方があるそうで、IT用語辞典 e-Wordから一部説明を引用します。

コンピュータに文書や情報の持つ意味を正確に解釈させ、文書の関連付けや情報収集などの処理を自動的に行わせる技術

コンピュータ側に、より正確に解釈させるため、HTMLは.htmlファイルに、JavaScriptは.jsファイルに混在させずにちゃんと書こうぜ、っていうことです。それを踏まえて、今回は、JavaScriptは.jsファイルに記述しよう!onclickを書き直そう!の回をお送りします。

onclick属性をaddEventListenerで書き換える

onclick属性は、○○が△△されたら□□する、というように、特定の要素(○○)に対して処理を行うきっかけ(△△)があったら、処理をする(□□)という橋渡しの役割をします。これを.jsファイルに書き換える場合には、addEventListnerを使います。

[取得したい要素]:先ほどの説明でいうと、○○にあたる部分、今回はスタートとストップのボタンですが、ここではスタート側のみ記述していきます。元の.htmlファイルではidを使って指定していなかったので、以下のように書き直します。

HTML側で付与されたidを参照するために「このidを持っている要素を、ページの中から見つけてくる!」と指示を出す必要があります。この指示を出すには、document.getElementByIdを使います。今回はこのコは詳しく触れません 。また後日。

今回は、startというidをもつ要素を取ってきてほしいので、

これを最初に出てきたaddEventListenerと組み合わせます。取得した要素を、start_btn変数に入れています。

残った2つは、何をしたら→クリックしたら、どの関数→start_slot なので、それぞれを書き直して、できたー!

・・・と思ったのですが、スロットが回ってくれません。
GoogleChromeのデベロッパーツールでエラー内容を確認してみました。デベロッパーツールについては「クローム 検証ツール」「クローム デベロッパーツール」等で使い方を検索してみてください。

デベロッパーツールで検証した結果、エラーは以下のとおり。

「エラーの種類:キャッチできず nullの’addEventListener’プロパティが読み取れない」

なぜnullになるのかを想定してみると、

  • 書いたコードがどこか間違っていてnullになっている
  • それ以外の理由で要素が取得できなくてnullになっている

1つ目のコード間違いについては、「見た目は間違っていない、けど、実はどこかに見落としがあるかも」・・・と自分を疑って、念のため、.htmlファイルの中、bodyの閉じタグ直前に直接scriptタグを入れてみました。もしコードに間違いがあれば、どこに書いたとしても同じエラーになるはずですが・・・、動きました。つまり今回のエラーはコード間違いが原因ではない、とわかりました。まずは一歩前進。

では、どこが問題なのか?addEventListenerは、直前のstart_btnという変数を受けているので、そこの値が取れているか?を確認する必要がありそうです。

結論から言うと、addEventListenerの前にある、start_btn、つまりgetElementById(“start”)の値が取れていなかったことがnullの原因でした。

htmlファイル内のscriptタグの位置

外部の.jsファイルを読み込もうとするとエラーになり、.htmlファイルに直接書くとエラーが出ない。
となると、問題は.jsファイルやその中身ではなさそうです。それを踏まえて、.htmlファイルを確認しました。

ページは上から順番に読み込まれて処理されていくので、.jsファイル読み込み・処理〜bodyの中身読み込み、の順番になります。id=”start”を持つ要素が読み込まれていない、値が無いのでnullがかえってくるんですね・・・。

直接scriptタグの中にJavaScriptを書いた時には、

getElementByIdが実行されるタイミングに、id=”start”を持つ要素は読み込まれているので処理ができました。

最終的に、外部の.jsファイルを読み込ませるタグを、bodyの閉じタグ直前に移動して、無事にスロットが動作するようになりました。めでたし。

今回は、addEventListenerについてお送りしました。