JavaScriptでアプリを作成しました【3】【超基礎TodoList 】

##はじめに

####学習するに至った経緯

2020年より、未経験からエンジニアへの転職を目指し、某プログラミングスクールへ通う。
入学後、『Ruby』を未経験から学ぶ人が多いのと『Ruby』の求人が思っていた以上に少ないので、
卒業後、フロントエンドのエンジニアを目指す事に。
Javascriptの学習した事を言語化し、認識の深化による備忘録として記載。

##【作成にあたり学習した事】
- Javascriptとは
- アプリケーションの作り方
- データ型、型変換
- 関数
- if文(条件分岐)
- for文(繰り返し文)
- オブジェクトの操作
- ブラウザーAPI（document）

##プログラムを書くポイント

- 小さく作って小さく動かす。
- 最初にタスクを明確にして、作成順を決める。

####TodoListのタスクの明確化と作成順

①【HTML】Todo入力ホームを整える
②【javascript】　Todoを表示・保存
③【javascript】　Todoを削除
④【javascript】　Todoを完了


##JavaScript
####JavaScriptとは
- HTMLからjavascriptを読み込み、ブラウザがjavascriptを実行する。
- JavaSciptが見た目を動的に変える事ができる。
- ブラウザ上で実行される唯一のプログラミング言語。

####JavaScriptで出来ること
- アニメーション（例 : crazy wedding ）
- ユーザー操作に合わせた見た目の変更（例 : Nike ）
- API（APIとは、バックエンドからデータを提供する仕組み事）
- バックエンドでも実行できる
- バックエンド実行環境はNode.js

##ブラウザーAPIとは
『ブラウザーAPI』は、Webブラウザーに組込まれていて、ブラウザーやコンピューターの環境の情報を取得し、これを使って役に立つ複雑な事を行えるようにするもの。 
例えば Geolocation API は位置情報を取得するための簡単な JavaScript 構造を提供するので、グーグルマップにあなたの居場所を表示するような事ができるなど。
裏で実際にはブラウザーは低レベル (例えば C++) の複雑なコードをいくつか使ってデバイスの GPS 機器 (あるいは位置情報を得られる他のなんだか) と通信し、位置情報を取得し、コードから利用できるようにブラウザー環境に情報を戻しているが、ここでもこの複雑な事柄は API で抽象化され隠蔽される。


####用語一覧 ・ 基本操作 ・ 機能
#### inputタグ
『input』タグとは、formタグで作成したフォームの中でテキスト入力欄やボタンなどの部品を作成する要素。部品はtype属性の値に指定することが可能で、一行テキストボックス、チェックボックス、ラジオボタン、実行ボタン、リセットボタンなどの部品を作成することができる。input要素に入力された情報は、データとしてサーバに送信される。

```
例:type="text"：1行テキストボックスを作る。  
<input type="text" name="text" value="初期値（任意の値）">
```
#### autocomplete=""
form要素に 『autocomplete=""』 を追加すると、
オートコンプリート機能（入力内容の自動補完）を有効にするかどうかを指定できる。
autocomplete属性を省略した場合は、オートコンプリート機能が有効になる。
オートコンプリート機能が有効になっている場合は、過去に入力した内容が入力候補として表示される。（対応しているブラウザのみ）

```
autocomplete="on"   オートコンプリートを有効にする （初期値）
autocomplete="off"  オートコンプリートを無効にする
```
####document
- ブラウザAPIの一種
- ブラウザに読み込まれたWEBページの情報を扱っている
- JavaScriptの機能ではないので注意

####documentを使ってみる
①『検証ツール』⇨ Console

```
②　＞document.getElementById('input')と入力すると③が表示
③  <input type=​"text" id=​"input" placeholder=​"TODOを入力する" autocomplete=​"off">​
```


```
④　＞document.getElementById('input').valueと入力すると⑤が表示
⑤  text(TODOを入力する)の中身に入力した文字が表示
```

##jsのファイルから値を取る
####データを取るタイミング
#####ユーザーがエンターを押した時 　⇨　 必要な知識：① 変数、② 関数、③ addEventLister 
####① 変数
#####データの入れ物 ⇨ 使い所：データを使い回したい時 
- let：値の再代入が可能
- const : 値の再代入が不可　定数の宣言
- var : letとほぼ同じで、昔の記法　今はあまり使用しない

####② 関数
#####一連の処理を一つの処理としてまとめたもの ⇨ 使い所：同じ処理を使い回したい時

####③ addEventLister 
#####特定のイベントが起きた時にJavaScriptの処理を追加するためのブラウザAPIの機能<br>⇨ 使い所：イベントが起きた時に処理を追加したい時

```
ターゲット.addEventListener(イベント名、関数);
```

####event.preventDefault()
#####event.preventDefaultメソッドは、submitイベントの発生元であるフォームが持つデフォルトの動作をキャンセルするメソッド。フォームが持つデフォルトの動作とは、フォームの内容を指定したURLへ送信するという動作。

```
form.addEventListener('submit',function(event) {
// submitイベントの本来の動作を止める
    event.preventDefault();
console.log(input.text)
});
```
##取得したフォームの値をHTML上に追加する
####ulとliタグを使って、リストとして情報を追加
#####createElement()メソッド
JavaScript で HTML 要素を動的に生成するには createElement() メソッドを使用する。

```
const element = document.createElement(タグ名)
```
crreateElement() メソッドで生成した要素を、実際の HTML 要素に追加することで HTML を動的に生成することができる。 HTML 要素への追加には appendChild() メソッドなどを使用する。

```
HTML要素.appendChild(生成した要素)
```
####データ型
#####データ型 = データの種類によってできる事を区別するために存在
#####JavaScriptのデータ型は大きく２つに分かれる

①　プリミティブ型　⇨　真偽値　数値　文字列
②　オブジェクト　⇨ オブジェクト　配列　関数

####if文
- 条件式がtrueなら実行する

```
if (条件式) {
// 条件式の評価結果がtrueなら実行する処理
}

if (true ) {
 console.log('実行');
}
```
####真偽値の判定
- falseになる値 ⇨ false 　undefined 　null 　0 　On 　NaN 　''(空文字)
- それ以外は全てtrue

##ローカルストレージに保存
####LocalStrage（ローカルストレージ）とは
#####LocalStrageとは、JavaScriptでデータをブラウザに保存する仕組み。永続的に保存。

```
データを保存する   localStorage.setItem('キー', 値)
データを取得する　　localStorage.getItem('キー')
```

##配列
####値に順序をつけて格納できるオブジェクト ⇨ 使い所：複数の値をまとめて扱いたい時
- []で定義
- ０から順に割り振る

```
const array = [ 'one','two','three'];
array[0]; //　=> 'one'
```

##ループ
####繰り返し処理を行うもの　⇨ 使い所：同じ処理を繰り返したい時
- forEach:配列の全要素に対して反復処理

```
const array = [1,2,3];

array.forEach(value => {
console.log(value * 2);
});
//2,4,6
```
####「push」とは
#####「push」はArray（配列）オブジェクトの組み込みメソッドとして用意されており、主に配列データの末尾に任意の要素を追加するために利用される。

```
let items = [1,2,3,4];
//配列「items」に数値データを追加する
items.push( 5,6,7,8 );

console.log( items );
実行結果
[1, 2, 3, 4, 5, 6, 7, 8]
```

##TODOを削除できる機能
####クリックしたら、要素を削除・非表示にする
####イベントの登録
#####「イベント」とは、「ブラウザ操作」のこと。<br> ⇨ クリックやインプット要素への入力、マウスオーバーなど。フロントエンド JavaScript 開発では、「いつ（＝イベント）」「何が起こる（＝DOM 操作）」か、という軸で発想する。

####addEventListener
#####イベントは、addEventListener メソッドで登録する。

```
// DOM 検索メソッドにより、HTML 要素の参照を得る
const button = document.querySelector('#btn-1');

// HTML 要素に対して、イベントのハンドラー関数を登録する
button.addEventListener('click', function(event) {
  // ここに、要素がクリックされたときに実行されるべき処理を記述する
例　button.remove();
});
```

##TODOに完了マークをつける機能
####クリックしたら、取り消し線を付ける
####classListで簡単にクラスを追加・削除する
#####JavaScriptでクラスを追加・削除する場合は、classList を使用すると 簡単に実現でき、クラスを追加する場合は add()、削除する場合は remove()を使う。 toggle()を使用すると、指定したクラスがない場合は追加、すでにある場合は削除する。

```
// 追加
elem.classList.add('クラス名');
// 削除
elem.classList.remove('クラス名');
// 追加・削除
elem.classList.toggle('クラス名');
```

##TODOアプリ完成
```
<!DOCTYPE html>
<html>

  <head>
    <title>TodoList Super basic 1</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div>
    <h1>TODOLIST</h1>
    <form id="form">
      <input type="text" id="input" placeholder="TODOを入力する" autocomplete="off">
    </form>
    <ul class="list" id="ul"></ul>
    </div>
    <script src="main.js"></script>
  </body>
</html>
```
```
'use strict';
{
//constでformを定義して、formを指定する
const form　= document.getElementById('form');
//inputの値を取る
const input = document.getElementById('input');
//ulの値を取る
const ul = document.getElementById('ul');
//local strageのデータ取得
const todos = JSON.parse(localStorage.getItem('todos'));
//todosが空でなければliタグを取得
if (todos) {
 todos.forEach(todo => {
    add(todo);
 })
}

//formに対して、イベントを追加
form.addEventListener('submit', function(event) {
// submitイベントに関して「preventDefault」する
  event.preventDefault();
// input.valueでテキスト中身の値を取る
//   console.log(input.value);
// add関数を呼び出す元
　add();  
});
// add関数を呼び出す
function add(todo){
//formに値が追加された時だけ表示　const li-input.value = ''をif文でくくる
//todoTextを変数宣言
let todoText = input.value;

if (todo) {
  todoText = todo.text;
}
//テキストの中身が一文字以上入力されていたら const li-input.value = '' を表示 
if (todoText)　{
//liタグを作成
　const li = document.createElement('li');
//ユーザーが取得した値をテキストへ入力
　li.innerText = todoText;
//liタグにクラスを指定し、追加する
　li.classList.add('list');
  if (todo && todo.completed) {
    li.classList.add('text-decoration-line-through');
  }
//右クリックしたら、liタグを削除する
  li.addEventListener('contextmenu',function(event) {
    //右クリックしたら出てくる表示をブロック
    event.preventDefault();
    li.remove();
    //ローカルステージに反映
    saveData();
  });
//左クリックしたら、完了線を付ける
li.addEventListener('click',function(){
    li.classList.toggle('text-decoration-line-through');
    saveData();
});

//ulタグの子としてliを追加
  ul.appendChild(li);
//投稿をしたら空にする
　input.value = '';
//関数追加
  saveData();
}
}
function saveData() {
// liタグのデータを取ってくる
　const lists = document.querySelectorAll('li');
//console.log(lists);
//新しい配列を作成
　let todos = [];

//liタグのテキスト情報を全て取得
　lists.forEach(list => {
    let todo = {
      text: list.innerText,
      completed: list.classList.contains('text-decoration-line-through')
    };
    todos.push(todo);
    // console.log(list.innerText);
});
//ローカルステージに保存
　localStorage.setItem('todos', JSON.stringify(todos));
}
}
```
##参考サイト
[JavaScriptの「基礎」が1時間で分かる「超」入門講座【初心者向け】]
(https://www.youtube.com/watch?v=E08jeQBa1D0&t=1287s)
[Web API の紹介]
(https://developer.mozilla.org/ja/docs/Learn/JavaScript/Client-side_web_APIs/Introduction)
[【JavaScript】event.preventDefault()が何をするのか]
(https://qiita.com/yokoto/items/27c56ebc4b818167ef9e)
[JavaScriptでcreateElementメソッドを使いHTMLを動的生成する方法を現役エンジニアが解説【初心者向け】]
(https://techacademy.jp/magazine/36505)
[JavaScriptのLocalStrage（ローカルストレージ） の使い方を現役エンジニアが解説【初心者向け】]
(https://techacademy.jp/magazine/19623)
[【JavaScript入門】pushで配列に要素を追加する方法(連想配列/pop)]
(https://www.sejuku.net/blog/84475)
[JavaScript超基礎講座！イベント処理を学ぶ]
(https://www.hypertextcandy.com/vanilla-javascript-event)
[JavaScript: classListで簡単にクラスを追加・削除する]
(https://step-learn.com/article/javascript/109-classlist.html)