【JavaScript】mozillaのJavaScriptチュートリアルをやってみる①

## 前提
* HTML
* CSS

を軽く知ってるくらいで大丈夫だと思います。

チュートリアルを見てなんじゃこりゃ？となった人向けに、なるべく簡単に書いてみました。

## 参考ページ

https://developer.mozilla.org/ja/docs/Learn/JavaScript/First_steps/What_is_JavaScript

## JavaScriptを体験してみる

1、まず`<p>`タグで文字を表示させます。

```html:.html
<p>Player 1: Chris</p>
```

2、CSSで文字を装飾をします。
装飾についてはあまり気にしなくて大丈夫です。

```html:.html
<style>
p {
  font-family: 'helvetica neue', helvetica, sans-serif;
  letter-spacing: 1px;
  text-transform: uppercase;
  text-align: center;
  border: 2px solid rgba(0,0,200,0.6);
  color: rgba(0,0,200,0.6);
  box-shadow: 1px 1px 2px rgba(0,0,200,0.4);
  border-radius: 10px;
  padding: 3px 10px;
  display: inline-block;
  cursor: pointer;
}
</style>

<p>Player 1: Chris</p>
```

3、JavaScriptで動的なふるまいを実装します。

```html:.html
<style>
p {
  font-family: 'helvetica neue', helvetica, sans-serif;
  letter-spacing: 1px;
  text-transform: uppercase;
  text-align: center;
  border: 2px solid rgba(0,0,200,0.6);
  color: rgba(0,0,200,0.6);
  box-shadow: 1px 1px 2px rgba(0,0,200,0.4);
  border-radius: 10px;
  padding: 3px 10px;
  display: inline-block;
  cursor: pointer;
}
</style>

<p>Player 1: Chris</p>

<script>
//動作させる場所をparaと定義する
const para = document.querySelector('p');
//para(p)のクリックでupdateNameが実行されるようする
para.addEventListener('click', updateName);
//updateNmaeの定義
function updateName() {
    //入力ダイアログを表示
    let name = prompt('名前を入力して下さい');
    //paraを書き換える
    para.textContent = 'Player 1: ' + name;
}
</script>
```
これで完成です！

名前を入力すると`Player 1: Chris`が`'Player 1: ' + name`に書き換わってますね！

あと`function updateName`を定義する前に使っていますが何やら動くようです。

動きを見たい方は見本をどうぞ（[見本](https://mdn.github.io/learning-area/javascript/introduction-to-js-1/what-is-js/javascript-label.html)）

### 簡単な説明

ワード|説明
---|---
let 変数名|再代入できる変数
const 変数名|再代入できない変数
Document.querySelector()|指定されたセレクターまたはセレクターのグループに一致する、文書内の最初の Element を返します。文字列は妥当なCSSセレクターのみ。
.addEventListener|クリック等のイベント処理を実行するメソッド
function 関数名|複数の処理の塊（セットのようなもの）
prompt()|入力ダイアログを表示させる（'hoge, デフォルト値'）
node.textContent|nodeのテキスト情報の取得や設定をする

## APIってのがある
API（Application Programming Interface）とは、難しいコードが簡単に実装できるようになる便利ツールの事です。

家具に例えると、木材の切り出しや設計などを一からするより、パーツやネジなどがセットになっていると簡単につくれますよね？それがAPIです。

## APIには２種類ある
### ブラウザAPI
ブラウザに組み込まれていて、コンピューターを取り巻く環境からデータの取り出しや複雑なことをしてくれる。

API|説明
---|---
DOM API|HTMLとCSSの操作を可能にします。
Geolocation API|地理的な情報を取得します。
Canvas|2Dのグラフィックアニメーション
WebGL|3Dのグラフィックアニメーション
HTMLMediaElement|音声・動画をウェブページで再生
WebRTC|リアルタイムな音声・動画をウェブページで再生

### サードパーティーAPI
ブラウザーには組み込まれておらず、普通はウェブ上のどこかからそのコードと情報を探さなければなりません。

API|説明
---|---
Twitter API|ツイートを表示できる
Google マップ API|地図の埋め込みができる

##内部のJavaScript
とりあえずHTML内部に書くJavaScriptの内容は外部と同じなので流し見でOKです。

一行目の`DOMContentLoaded`が違うことだけ覚えておきましょう！

```html:.html
<head>
    <meta charset="utf-8">
    <title>Apply JavaScript example</title>
    <script>
        // JavaScript をここに書きます
        document.addEventListener("DOMContentLoaded", function() {
            function createParagraph() {
                let para = document.createElement('p');
                para.textContent = 'ボタンが押されました!';
                document.body.appendChild(para);
            }

            const buttons = document.querySelectorAll('button');

            for(let i = 0; i < buttons.length ; i++) {
                buttons[i].addEventListener('click', createParagraph);
            }
        });
    </script>
</head>
<body>
    <button>Click me</button>
</body>
```

## 外部のJavaScript
JavaScriptはHTMLファイル内に書くのではなく、別の外部ファイル（hoge.js）に記述するようにします。HTMLの途中にJavaScriptを書くとコードを汚してしまうのでできるだけJSファイルを別で作成します。

```html:.html
<head>
    <script src="script.js" defer></script>
</head>
```

```javascript:script.js
//createParagraphを定義する
function createParagraph() {
    //<p>タグを作成するparaを定義する
    let para = document.createElement('p');
    //paraにテキストを入力します。
    para.textContent = 'ボタンが押されました!';
    ///bodyの最後にparaとその子孫を追加します。
    document.body.appendChild(para);
}

//<button>をbuttonsと定義する
const buttons = document.querySelectorAll('button');

//全ての<button>で実行するfor文
for(let i = 0; i < buttons.length ; i++) {
    //ボタンをクリックするとcreateParagraphが実行される
    buttons[i].addEventListener('click', createParagraph);
}
```

ワード|説明
---|---
document.createElement()| tagNameで指定された HTML 要素を生成
Node.textContent|ノードおよびその子孫のテキストの内容を表します。
Node.appendChild()|特定の親ノードの子ノードリストの末尾にノードを追加します。
document.querySelectorAll()|CSSセレクターに一致する文書中の要素のリストを示す静的なNodeListを返します。
for文（繰り返し）|括弧で囲みセミコロンで区切った3つの引数と、続いてループ内で実行される文から成るループを構成します。
Array.length|配列の要素の数を設定または取得します。

## JavaScriptのfor文

```javascript:.js
for ([initialization]; [condition]; [final-expression]) {
    statement
}
```

##### initialization（初期変数）
ループが始まる前に一度だけ評価される式または変数宣言。
普通はカウンター変数を初期化するために使われます。この式では任意で、varキーワードを用いて新しい変数を宣言することもできます。 varで宣言された変数はループ内のローカル変数にはなりません。letで宣言された変数は文内のローカル変数になります。

##### condition（条件式）
ループのそれぞれの反復処理が行われる前に評価される式です。
この式がtrueと評価された場合は、 statementが実行されます。この条件テストは省略可能です。省略された場合は、条件は常にtrueに評価されます。もしこの式がfalseと評価された場合は、実行はfor構造に続く最初の式に飛びます。

##### final-expression（最終式）
ループのそれぞれの反復処理の最後に評価される式です。これは、次のconditionの評価前に行われます。一般的には、カウンター変数を更新または増加するために使われます。

##### statement（命令文）
条件がtrueと評価された場合に限り実行される文です。
ループ内で複数の文を実行するには、ブロック文 ({ ... }) を使用して文をグループ化します。ループ内で文を実行しないようにするには、空文 (;) を使用。

### 先程のfor文をもう一度確認

```javascript:.js
for(let i = 0; i < buttons.length; i++) {
    buttons[i].addEventListener('click', createParagraph);
}

let i = 0; //初期値
i < buttons.length; //ボタンの数だけ
i++ //カウントアップ

//第二引数は空白だと全てがTrueになるので空白でも動く。
//第三引数を空白にするとクラッシュする。
```

## スクリプトの読み込み方針
ページ上のすべてのHTMLが現れた順に読み込まれます。JavaScriptを使用してページ上の要素を操作している場合、<b>何かをしようとするHTMLの前にJavaScriptが読み込まれ解析されてもコードは機能しません</b>。

### 内部の場合

`DOMContentLoaded`は、最初のHTMLの読み込みと解析が完了したとき、スタイルシート、画像、サブフレームの読み込みが完了するのを待たずに発生します。このブロック内のJavaScriptはそのイベントが発生するまで実行されないためエラーは回避されます

```html:.html
<script>
document.addEventListener("DOMContentLoaded", function() {
  ...
});
</script>
```

### 外部の場合

```html:.html
<script src="script.js" defer></script>
```

`defer`で問題を解決します。

この場合スクリプトとHTMLの両方が同時に読み込まれコードが機能します。

`defer`は外部スクリプトに対してのみ機能します。

この問題に対する昔ながらの解決策は、すべてのHTMLが解析された後に読み込まれるように、`</body>` の直前にscript要素を置くことでした。この解決策の問題点は、HTML DOMが読み込まれるまでスクリプトの読み込みと解析が完全にブロックされることで、JavaScriptが沢山ある大規模なサイトでは、これは大きなパフォーマンス上の問題を引き起こす可能性がありサイトを遅くしてしまいます。

#### asyncとdefer


有無|説明
---|---
無し|直列処理
async|並列処理。読み込みが完了したJavaScriptから実行される。<br/>依存関係なしでスクリプトを単独ですぐに実行できる場合は、asyncを使用します。
defer|並列処理。JavaScriptが書かれた順に実行される。<br/>スクリプトが他のスクリプトや DOM配置に依存している場合は、deferを使用してスクリプトを読み込み、対応するscript要素をブラウザーで実行して欲しい順序で配置します。

## まとめ
* 色んなオブジェクトやメソッドがあるので少しずつ覚えていく
* 難しいコードを簡単にできるAPIってのがある
* JavaScriptは外部ファイル（.js）に書く
* JavaScriptの読み込み順に注意する

どの要素（CSSクラス）で何をするか？という順でコードが書かれている。

次は「JavaScriptへの最初のダイブ」のチュートリアルをやってみようと思います。