フロントエンド学習記No.1 JavaScriptの基礎に触れる

## はじめに
初めまして。10月より某SES企業でエンジニアとして働き始めた「rky」と申します。
これまであまり経験のなかったフロントエンド技術について、最近学習を始めました。内容は基礎的なものが多くなるかと思いますが、自分自身の学びを記録するとともに、他の初学者の方々の学習にも役立つ情報を提供できればと考え学習記録をつけていくことにしました！


## 学習内容
学習方法については以下のように考えています。
1. 目標とするアプリケーションや機能を考える。
2. JavaScriptを使って実装する。
3. TypeScriptで書き直す。
4. Vue.jsなどのフレームワークを使って再実装する。
 これはあくまで現時点での計画なので、進行に応じて変更する可能性もあります！
 これまで学習はほとんど書籍等による「インプット」に偏っていましたが、今回は「アウトプット」を重視して、学んでいきたいと思い、このような方法を試してみることにしました。
 
## 目標物
* +ボタンをクリックしたら数字を1足す
* -ボタンをクリックしたら数字が1引く
* 数値に対応してメーターが変化する
* 数値が10を超えた時にレベルアップする。
* レベルアップした際に、祝福のメッセージが表示される
とこんな感じのよくわからないアプリを作っていきたいと思います！
ただの思いつきですが、目標物を考えるのに時間を割くよりも、思いついたものを形にする方を重視していきます！
簡単なDOM操作の復習と、Progakuの「フロントエンド学習会」で知った、SVGを取り入れることを目的にしたため、このような機能にしました！

## 完成品
https://github.com/rikuya98/javascript_study/tree/master#readme
ひとまずこんな感じとなりました笑

## ソースコード

```index.html
<body>
    <h2>ステータス</h2>
    <p>Lv. 
        <span id="LevelCount">1</span>
    </p>
<p id="counter">0</p>
<button id="countup">+</button>
<button id="countdown">−</button>

<svg width="210"height="50">
    <rect width="200" height="30" x="5" y="5" fill="none" stroke="black" stroke-width="2"></rect>
    <rect id="meter" width="0" height="30" x="5" y="5" fill="blue"></rect>
  </svg>
<script src="js/main.js"></script>
</body>
```
```javascript main.js
const INCREMENT = 1
const DECREMENT = -1

function updateMeter(counterValue) {
    const meter = document.querySelector('#meter');
    const maxWidth = 200;
    const newWidth = (maxWidth / 10) * counterValue;
    meter.setAttribute('width', newWidth);
}

const counterElement = document.querySelector('#counter');
const levelElement = document.querySelector('#LevelCount')

function updateCounter(amount) {
    let currentValue = parseInt(counterElement.textContent);
    let levelValue = parseInt(levelElement.textContent);

    if (amount > 0 && currentValue < 10) {
        currentValue += amount;
    } else if (amount < 0 && currentValue > 0) {
        currentValue += amount;
    } else if (currentValue === 10) {
        levelElement.textContent = levelValue + 1;
        currentValue = 0;
        window.alert('おめでとうございます！レベルアップしました！');
    }

    counterElement.textContent = currentValue;
    updateMeter(currentValue)
}

const countUpButton = document.querySelector('#countup');
countUpButton.addEventListener('click', () => updateCounter(INCREMENT));

const countDownButton = document.querySelector('#countdown');
countDownButton.addEventListener('click', () => updateCounter(DECREMENT));
```

CSSは使用していません。

それでは解説していきます。といってもほとんどの方が知っているような知識しか出ていないかもしれまんせが・・・笑

まずはSVGの箇所です
```
<svg width="210"height="50">
    <rect width="200" height="30" x="5" y="5" fill="none" stroke="black" stroke-width="2"></rect>
    <rect id="meter" width="0" height="30" x="5" y="5" fill="blue"></rect>
  </svg>
  ```
  以下のドキュメントを参考にしました。
  
https://developer.mozilla.org/en-US/docs/Web/SVG

ザッと見ましたが、できることが多過ぎて収拾つかなかったので四角形を描画するrectタグのみ使って簡単に実装していきます。

### svgタグ
ざっくり言うとSVGを描画する範囲の設定するタグみたいです。
今回でいうとwidthが210heightが50の範囲で書きますよと設定している感じです。

### rectタグ
四角形を描画するための基本的なタグです。
widthとheightは四角形の大きさを設定しています。
xとyは座標です。svgタグで設定した範囲内を基基準にしてどこに描画するかを設定します。
fillは図形の色、strokeは図形の外枠を設定できます！

今回は、全く同じ大きさ、座標のrectを２つ用意して、一つは外枠有りで内部を透明に、もう一つは外枠無しで内部を青にし、それらをjavascriptで操作する事で実装しました。


### updateMeter関数
カウンターの値に応じてメータを操作する関数です。
``` 
function updateMeter(counterValue) {
    const meter = document.querySelector('#meter');
    const maxWidth = 200;
    const newWidth = (maxWidth / 10) * counterValue;
    meter.setAttribute('width', newWidth);
}
```
青色の図形の要素を取得して横幅の最大値を定義。
カウントの上限はひとまず10とします。
図形の最大値を１０で割って、引数で渡ってきた現在のカウンターの値で掛け算。
こうすることでカウンターの値に合わせて均一に要素の　横幅を変動させることができます。
最後にsetAttributeを使用して、カウンターの値と連動したwidth値をmeterにセット。

https://developer.mozilla.org/ja/docs/Web/API/Element/setAttribute

setAttributeは
第１引数に変更したい属性、第２引数に設定したい値
を入れることで要素の属性を変更することができるようです。


### updateCounter関数
カウンターの値を変動させる関数です。
+1か-1のどちらかを受け取り、カウンターの値を増減させます。
カウンター機能に上限を設定したり、レベルアップ機能が入るという謎仕様により、0より小さくできないように10より大きくならないようにする制限が必要になってしまいました・・・
```
function updateCounter(amount) {
    let currentValue = parseInt(counterElement.textContent);
    let levelValue = parseInt(levelElement.textContent);

    if (amount > 0 && currentValue < 10) {
        currentValue += amount;
    } else if (amount < 0 && currentValue > 0) {
        currentValue += amount;
    } else if (currentValue === 10) {
        levelElement.textContent = levelValue + 1;
        currentValue = 0;
        window.alert('おめでとうございます！レベルアップしました！');
    }

    counterElement.textContent = currentValue;
    updateMeter(currentValue)
}
```

""" +もしくは-ボタンクリック時に、これらの処理を実行させる。
```
const countUpButton = document.querySelector('#countup');
countUpButton.addEventListener('click', () => updateCounter(INCREMENT));

const countDownButton = document.querySelector('#countdown');
countDownButton.addEventListener('click', () => updateCounter(DECREMENT));
```

### まとめ
ということで初歩的な内容でしたが、学んだことを掛け合わせてjavascriptであそんでみました。
HTML要素を取得して、イベントを発火させたり、属性値や値を変更するjavascriptの基本の復習しながら楽しめたように思います。次回は、これらをtypescript、Vueで置き換えてみたいと思います。