JavaScript FizzBuzz問題の作り方

##目次
 - はじめに
 - FizzBuzz問題の作り方
 - HTML
 - JavaScript
 - 学んだこと
 - おわりに
 
##はじめに
今回はJavascriptの基本的な概念`DOM`を操作して、FizzBuzz問題を作っていきます。
イチから全部作り方を書くというよりは、作っていく流れを書き、
実際に作る中で僕が躓いたり、ここは大事だなと感じた箇所などを説明していきます。
同じようなことで行き詰まっている初心者の方のお力になれれば幸いです。

##FizzBuzz問題の作り方
基本的にHTMLとJavaScriptを使って作成します。
CSSは特に使いません。
HTMLの要素も至ってシンプルです。
なぜなら、今回の実装では**JavaScriptを使ってDOMを操作すること**が目的だからです。
HTMLで作った画面を作り、それに対してJavaScriptで色々操作していく、という流れになります。

###HTML

まずはHTMLから作っていきます。
HTMLの作りはとてもシンプルで簡単なものです。

見出し `h1タグ` 
２つの数値入力ボックス `pタグ` 
実行ボタン `buttonタグ`
「出力」 `pタグ`

それだけです。
見た目としては以上になります。

そして、大事な`scriptタグ`
このタグがあることで簡単にHTMLとJavaScriptを繋げることが出来ます。
このタグがないとJavaScriptを発動出来ません。
これだけは忘れずに書いてください。

色々決まりはありますが、
基本的に`scriptタグ`はbodyの末尾辺りに置く慣習になっています。

JavaScriptは違うページに専用ファイルとして書いていきます。
(文が長くなって読みにくくなるのを防ぐためであったり、それもまた慣習となっています。)
そのためsrc属性を使って、リンク先だけを書いておきます。

```html

<body>
  <h1>FizzBuzz問題</h1>
  <p>FizzNum: <input type="text" name="fizzes" id="fizz" placeholder="整数値を入力してください"></p>
  <p>BuzzNum:<input type="text" name="buzzes" id="buzz" placeholder="整数値を入力してください"></p>
  <button value="実行" id="btn">実行</button>
  <div id="output">
    <p>【出力】</p>
  </div>

  <script src="main.js"></script>
</body>
```

またJavaScriptを使ってDOMを操作するのに必要になるのが`id`です。
何箇所にidがセットされているのがわかるかと思います。
このidが後々非常に役に立ちます。


HTMLは以上で完了です。
ブラウザに映る元々の表示の役割を担ってくれています。
出来ることはここまでです！
これから先の実装はJavaScriptに任せることとします。



##JavaScript

```javascript

//FizzNum, BuzzNumに数値を入力し、実行を押したときの挙動//


//HTMLの中からIdがbtnの要素を取得
const btn = document.getElementById('btn');

//ボタン要素のクリックイベントをトリガーにコールバック処理を作成
btn.addEventListener('click', () => {

```

次にJavaScriptでの処理です。
別ファイルに作ったmain.jsに書き込んでいきます。

基本的にコードは**始まりはこれを書かなければいけない**という厳密な決まりはないので、なにから書いてもいいはずです。
ただ、通常コードは上から下に読み込まれていくので、その点は考える必要があります。

まず、要素を`id`から取得します。そのためにhtmlで要素に`id`を付与する訳です。
その要素に対してイベント(何かしらの処理を行う)を発動する行為が、`EventListener`です。
この流れはJavaScriptでは鉄板です。何回も使います。
指が覚えるくらい繰り返してもいいと思います。

```JavaScript

//入力値の取得//

  //HTMLの中からIdがfizzの要素を取得
  const elemFizzNumber = document.getElementById('fizz');

  //fizzNumのinputに入力された数字から値を取得
  const fizzNumber = elemFizzNumber.value;

  //HTMLの中からIdがbuzzの要素を取得
  const elemBuzzNumber = document.getElementById('buzz');

  //BuzzNunのinputに入力された数字から値を取得
  const buzzNumber = elemBuzzNumber.value;

```

この次も要素の取得の流れは続きます。
要素を取得し、更に要素に入力された値を取得しています。
`value`が登場してきます。
取得した要素を後でたくさん使うので、先に色々と取得しておく必要があります。
この辺りの考え方もプログラミングならでは、ですね。

```JavaScript

//結果情報のベース作成//

  //HTMLの中からIdがoutputの要素を取得
  const outputArea = document.getElementById('output');

  //結果要素の子要素を取得
  outputArea.innerHTML = '';

  //pタグの要素を作成
  const ptag = document.createElement('p');

  //pタグの要素に結果情報ヘッダーの固定値をセット
  ptag.textContent = '【出力】';

  //結果要素の子要素としてpタグの要素を追加
  outputArea.appendChild(ptag);

```

必要な要素が取得できたら、次はその要素をブラウザに表示するための処理が必要です。
次に`createElement`が出てきます。
要素を取得したり、要素を作り出したり、なんせ要素は大事です。
この辺りも一連の流れになっているので、繰り返せば頭に自然に入ってくるはずです。

一文一文に意味があり、
やること(必要な処理)を流れで考えている、のがわかるかと思います。

```JavaScript

//結果情報の中身を作成//

  //fizzbuzz問題のループ文

  // 変数iを定義し、iが100より小さい場合、iに1ずつ足していく処理を実行
  for (let i = 1; i < 100; i++) {

    //バリューを取得するための変数を定義
    let value = '';

    //iがfizzes、buzzesの両方の数値の倍数である場合の処理
    if (i % fizzNumber === 0 && i % buzzNumber === 0) {

      //ブラウザに表示するための文字列と取得した値をバリューとして用意
      value = "FizzBuzz" + " " + i;

      //がiがfizzesの倍数である場合の処理
    } else if (i % fizzNumber === 0) {

      //ブラウザに表示するための文字列と取得した値をバリューとして用意
      value = "Fizz" + " " + i;

      //がiがbuzzesの倍数である場合の処理
    } else if (i % buzzNumber === 0) {

      //ブラウザに表示するための文字列と取得した値をバリューとして用意
      value = "Buzz" + " " + i;

      //iがどちらの倍数でもない場合の処理
    } else {

      //何も表示させないものとして用意
      value = '';
    }

```

次は肝心のFizzBuzz文です。
`for文`の中で`if文`を用います。
最初に取得した要素もここで使用する訳です。
必要なものを先に準備して、後で使う。それがイメージできれば、構文も考えやすくなります。

言葉にはできてもコードで書くのは難しいです。
`for文`にしろ、`if文`にしろ、プログラミングには書き方(法則)があるので、それを自分の脳内に落とし込む作業が必要になります。
頭に入ってしまえば、後は必要なときに取り出すだけです。

これだけあれば、FizzBuzz文をブラウザに表示できます。
後は、エラーが出たときの処理を付け足したりして、より強固な機能を付け加えるといいかと思います。

以上が、FizzBuzz問題の作り方です。

以下、全体のコード

```JavaScript

`use strict`

//FizzNum, BuzzNumに数値を入力し、実行を押したときの挙動//


//HTMLの中からIdがbtnの要素を取得
const btn = document.getElementById('btn');

//ボタン要素のクリックイベントをトリガーにコールバック処理を作成
btn.addEventListener('click', () => {

  //入力値の取得//

  //HTMLの中からIdがfizzの要素を取得
  const elemFizzNumber = document.getElementById('fizz');

  //fizzNumのinputに入力された数字から値を取得
  const fizzNumber = elemFizzNumber.value;

  //HTMLの中からIdがbuzzの要素を取得
  const elemBuzzNumber = document.getElementById('buzz');

  //BuzzNunのinputに入力された数字から値を取得
  const buzzNumber = elemBuzzNumber.value;

  //結果情報のベース作成//

  //HTMLの中からIdがoutputの要素を取得
  const outputArea = document.getElementById('output');

  //結果要素の子要素を取得
  outputArea.innerHTML = '';

  //pタグの要素を作成
  const ptag = document.createElement('p');

  //pタグの要素に結果情報ヘッダーの固定値をセット
  ptag.textContent = '【出力】';

  //結果要素の子要素としてpタグの要素を追加
  outputArea.appendChild(ptag);

  //結果情報の中身を作成//

  //fizzbuzz問題のループ文

  // 変数iを定義し、iが100より小さい場合、iに1ずつ足していく処理を実行
  for (let i = 1; i < 100; i++) {

    //バリューを取得するための変数を定義
    let value = '';

    //iがfizzes、buzzesの両方の数値の倍数である場合の処理
    if (i % fizzNumber === 0 && i % buzzNumber === 0) {

      //ブラウザに表示するための文字列と取得した値をバリューとして用意
      value = "FizzBuzz" + " " + i;

      //がiがfizzesの倍数である場合の処理
    } else if (i % fizzNumber === 0) {

      //ブラウザに表示するための文字列と取得した値をバリューとして用意
      value = "Fizz" + " " + i;

      //がiがbuzzesの倍数である場合の処理
    } else if (i % buzzNumber === 0) {

      //ブラウザに表示するための文字列と取得した値をバリューとして用意
      value = "Buzz" + " " + i;

      //iがどちらの倍数でもない場合の処理
    } else {

      //何も表示させないものとして用意
      value = '';
    }

    //要素を追加するためのpタグ要素を作成
    const fizzbuzz = document.createElement('p');

    //テキストの内容に、ループ文で取得した値を入力する
    fizzbuzz.textContent = value;

    //親要素であるdivタグの要素を取得
    const div = document.querySelector('div')

    //div要素の子要素として追加
    outputArea.appendChild(fizzbuzz);
　}
});

```

##学んだこと
一から何かを作るのは大変です。
私は一ヶ月ほどかかって今回のFizzBuzz問題の作り方を理解しました。
時間はかかりましたが、考えを頭に落とし込むにはそのくらいの時間をかけてもいいと思います。

例え簡単なFizzBuzz文であっても、本当にわからないことだらけでした。
わからないながらでも作っていき、その中で学んでいくことが大半です。

コード自体は学習したことをそのまま応用しているだけなので、難しいことは書いていません。
しかし、学んだことを応用する作業が非常に難しいです。

何を書けばいいかわからない(頭に浮かんでこないから)という問題は、私も例外なく陥りました。
そのくらい、プログラミングは生活から切り離されているもの(馴染みのないもの)なんだなと感じました。
こればっかりは繰り返して学んでいくしかないので、
プログラミングという概念を頭に埋め込んでいく時間が必要です。

また、DOM操作も初心者が躓く概念だと思います。
普段の生活でDOMのような考え方はありませんから、最初はよくわからないのも当然です。
しかし、JavaScriptを学ぶ上でDOMの概念は切っても切れないので、しっかり脳内に刻み込んでおく必要があります。

ここは踏ん張りどころです。一つ一つ乗り越えていくしかありません。
その過程で出来ないことが出来るようになっていくのはとても嬉しいものです。

教材で学習するのは最低限必要ですが、その先は何かを作れ、という先人達のアドバイスは本当にその通りだと思いました。

##おわりに
今回は私が初めて行った課題について説明しました。
今振り返ると簡単なことでも、振り返ると当初は全然わからず、頭を抱えていました。
初歩的なことでも初心者はわからないものです。

振り返ると、自分も少しは理解できていることに気づきます。
きっとプログラミング学習は、そんな小さな喜びの連続なんだと思っています。

毎日勉強して、新しいことを吸収していきたいものです。

人に説明するのも難しいものです。
と同時に、自身の学びにも繋がるので、随時アウトプットしていきます。

ありがとうございました。