ToDoリストアプリの作成 12-15日目 2024/10/18-21(お金持ちまでの道のり)

英国紳士風のお金持ちアンドロイドの絵です。 プログラミング

アプリの作成ってなんかついに実践って感じでワクワクしますね。頑張ります!

初めての人はお金持ちまでの道のり:0日目をまず読んでみてください!よろしくお願いします★

ToDoリストアプリの作成:HTML

HTMLファイルとJavaScriptファイルを作成して、アプリ作成のための基本的なセットアップをします。まずはHTMLから見ていきましょう。

タグと属性の一覧はこちら(復習や確認が必要な場合)
HTML初級編 1日目 2024/10/7(お金持ちまでの道のり)

これを確認しながらコードの解読をするとかなり捗ります!

addTask(関数)
1.<input type="text" id="new-task" placeholder="新しいタスクを入力">をtaskInputという箱に入れる
2.「宿題をやる」というテキストをtaskTextという箱に入れる

taskInput(変数)
<input type="text" id="new-task" placeholder="新しいタスクを入力">

taskText(変数)
taskInput.value(例:宿題をやる)

newTask(オブジェクト)
text: taskText(宿題をやる)
completed: false
※2つのプロパティを含むオブジェクト(プロパティ:値)

renderTask(関数)
<ul id="task-list"></ul>というオブジェクトをtaskListという箱に入れて、taskList.innerHTML = ""でリストのテキストデータを削除し、taskListの箱の中にあるオブジェクトを使って、新しいリスト項目(テキストデータ)を作成し直している
※※取得(HTML要素(オブジェクト))→削除(リストのテキストデータ部分)→取得したデータを使って再描画

taskList(変数)
<ul id="task-list"></ul>

task(オブジェクト)
配列tasksの一つ一つのオブジェクト(例:{text: “宿題をやる”, completed: false}

text(プロパティ)
“宿題をやる”というプロパティ
※プロパティは、オブジェクト+プロパティというセットで機能する。単品では機能しない。

task.text(オブジェクト+プロパティ)
オブジェクトtask+プロパティtext。これでプロパティの値にアクセスできる。
※プロパティは、オブジェクト+プロパティというセットで機能する。単品では機能しない。

listItem(変数)
空の <li></li> 要素が入っている

completeButton&deleteButton(変数)
新しく作成された <button> </button>要素のオブジェクトが入っている

completeTask(関数)
completeButtonがクリックされたら、そのインデックス番号のタスクのcompletedプロパティを反転させる

基本構造を確認

<!DOCTYPE html>:HTML5の宣言で、これによりブラウザが最新のHTMLを使います。
<html lang="ja">:ページの言語を日本語と指定しています。
<head>:ページに関するメタ情報を入れます。ここには、文字コード(<meta charset="UTF-8">)やページのタイトル(<title>ToDoリスト</title>)が入っています。
<body>:実際に表示される内容が入る部分です。ここに入力フォームやボタン、タスクリストが表示されます。

要素を確認

●<input type="text" id="new-task" placeholder="新しいタスクを入力">
・<input>は、ユーザーが情報を入力できる入力フィールドを作成するためのHTMLタグです。type="text"は、入力フィールドのタイプを指定するための属性です
(その他の属性例:type="password"type="email"type="number"など)
id="new-task"は、JavaScriptがこの要素を操作するための識別子です。③で使用されています。
・placeholderはユーザーが入力する前に、入力欄に表示するヒントを指定します。

和訳:
<input>タグを使って、ユーザーがテキストを入力できるフィールドを作成している。type="text"は、このフィールドが文字列の入力を受け付けることを指定し、id="new-task"はこの入力フィールドにnew-taskという一意の識別子を設定している。placeholder="新しいタスクを入力"は、入力欄に「新しいタスクを入力」という薄い案内文を表示し、ユーザーが何を入力すべきかを示している。

●<button onclick="addTask()">タスクを追加</button>
<button>:このボタンを押すと、タスクが追加されます。
onclick="addTask()"は、ボタンがクリックされたときにaddTask()というJavaScript関数を実行するためのものです。
●<ul id="task-list"></ul>
<ul id="task-list">だけでは、リストの「枠」だけが作成され、リスト項目(<li>タグ)はまだ作成されません。JavaScriptが動的にここにタスクを追加します。
●<script src="todo.js"></script>
<script src="todo.js"></script>todo.jsというJavaScriptファイルを読み込んで、ページに機能を追加しています。src(sourceの略)属性は、**外部スクリプトファイルの場所(パスやURL)**を指定するための属性。

ToDoリストアプリの作成:Javascript

上記のHTMLは基本的な入力欄とタスクのリストを表示するための部分です。次に、JavaScriptで動きを作りましょう。

JavaScriptの主な組み込み関数予約語についてはこちら
JavaScriptとは? 変数,if,switch 4日目 2024/10/10(お金持ちまでの道のり)

① タスクを管理する配列 tasks

和訳:
tasks(初登場)という変数に、タスクを管理するための空の配列を作成して代入している。

・let tasks: tasksという変数を宣言しています。tasksは配列型の変数で、複数のタスクをまとめて保持します。
・[]: 空の配列を初期化しています。最初はタスクがないため、配列の中身は空です。
・この後、タスクが追加されるたびに、このtasks配列に新しいタスクが追加されていきます。

「=」の使い方
・HTMLでは、属性 = 属性の値
・Javascriptでは、変数やプロパティ(メソッド) = 値
※メソッドは関数を含んだプロパティ

② addTask 関数 - タスクを追加する

和訳:
ユーザーが定義したaddTask(初登場)という新しいタスクを追加するための関数を定義している。

説明と和訳

このコードは、新しいタスクを追加するための関数であるaddTask()を定義しています。この関数は、ユーザーがタスクを入力し、それをリストに追加するために呼び出されます。

詳しい解説

  • function addTask():ここで、addTaskという関数が定義されています。この関数は、新しいタスクを追加する処理をまとめたものです。
  • 関数名は、自由に名前を付けることができるユーザー定義の名前です。ここでは、わかりやすく「タスクを追加する」という意味でaddTaskという名前が付けられています。(addTaskは、ここで定義されたため、この箇所では名称変更可能だが、以降の箇所では変更不可となる

※関数の呼び出しは、HTMLのボタンのクリックによって行われます。

③タスクの入力欄を取得(HTMLとの関係)

和訳:
taskInput(初登場)という変数に、組み込み関数document.getElementById('new-task')を使って、idが'new-task'であるHTMLの入力要素を取得し、次にそのtaskInput(先ほど取得した入力要素)の組み込みプロパティvalue(入力されたタスクのテキスト)をtaskText(初登場)という変数に代入している。

詳しい解説

  1. let taskInput = document.getElementById('new-task');
    • taskInputは、HTML内のid="new-task"を持つ要素を取得し、その要素を参照するために使う変数です。
    • document.getElementById('new-task')は、HTMLの中でid属性が"new-task"の要素を取得する組み込み関数です。**new-task**というID名は、HTML側で定義されており、変更できません。
    • taskInputはこの箇所で定義されるため、ここでは名称変更可能だが、以降の箇所では変更不可となる
  2. let taskText = taskInput.value;
    • taskTextは、taskInputに保存された入力要素の中にあるテキストの値を取得して保存する変数です。
    • taskInput.valueのvalueプロパティは、入力されたテキスト(タスクの内容)を取得するための組み込みプロパティで、名称は変更できません。
    • taskTextは、この箇所で定義されているため、ここでは名称変更可能
  3. 例えば「宿題をやる」というタスクを入力した場合
    • let taskInput = document.getElementById('new-task');で取得する要素は
      <input type="text" id="new-task" placeholder="新しいタスクを入力">
    • let taskText = taskInput.value;で取得する要素は
      宿題をやる

④空の入力をチェックし、エラーメッセージを表示

和訳:
もしtaskTextが空文字列なら、組み込み関数alertを使って「タスクを入力してください!」というメッセージを表示し、return(予約語)で関数の処理を終了する。

説明と和訳

このコードは、タスクの入力欄が空白かどうかを確認し、もし空白であれば警告メッセージを表示し、そこで処理を中断します。空白の場合は、タスクを追加する処理は行われません。

詳しい解説

  1. if (taskText === "")
    • **taskText(③で定義された変数)に保存されている値(ユーザーが入力したタスクの内容)が空文字列("")**であるかどうかを確認しています。もし空白なら、次の処理が実行されます。
    • taskTextはユーザーが入力したタスクの内容(例:宿題をやる)
      =は代入を意味し、値を変数に設定するために使われます。一方、===は厳密な比較を意味し、値と型の両方を比較して、等しいかどうかを確認します。
  2. alert("タスクを入力してください!");
    • alert()は、組み込み関数で、指定されたメッセージをポップアップウィンドウで表示するものです。ここでは、**「タスクを入力してください!」**というメッセージが表示されます。
    • alertは、JavaScriptにおける組み込み関数で、名称は変更できません。
  3. return;
    • returnは、関数の実行を途中で終了させるためのキーワードです。ここでは、タスクの入力が空白であった場合、タスクを追加する処理を終了します。returnも予約語で、名称は変更できません。
      return〇〇;なら値を返す、return;なら関数の処理を終了

⑤新しいタスクを作成し、リストに追加

和訳
newTask(初登場なので名称変更可)という変数に、text(初登場なので名称変更可)というプロパティにtaskText(③で定義されたので名称変更不可)を、completed(名称変更可能)というプロパティにfalseを設定したタスクのオブジェクトを作成して代入している。

ちょっと復習(オブジェクト)
let newTask = {
text: taskText, // "text"というプロパティ(キー)に、taskText(値)(変数)がセットされる
completed: false // "completed"というプロパティ(キー)に、false(値)がセットされる
};

説明と和訳

このコードは、新しいタスクをオブジェクトとして作成しています。オブジェクトには、タスクの内容(text)とその完了状態(completed)の2つのプロパティが含まれています。

詳しい解説

  1. let newTask = { ... };
    • newTaskという変数を作成し、タスクの情報を格納するオブジェクトを定義しています。
    • newTaskという変数名は自由に変更可能ですが、以降の箇所では変更不可。
  2. text: taskText
    • オブジェクトの**textプロパティに、ユーザーが入力したタスクのテキスト(taskText**)を代入しています。
    • textは、このオブジェクトのプロパティ名です。初なのでここでは自由に他の名前に変更できます(例えばdescriptionなど)。
    • **taskText**は変数ですが既出のためここでは名称変更不可です。
  3. completed: false
    • このオブジェクトの**completedプロパティは、そのタスクが完了しているかどうかを表すためのものです。ここでは、タスクが新規追加されたため、デフォルトでfalse**(未完了)に設定しています。
    • **completed**もプロパティ名なので、他の名前に変更可能です(例えばisDoneなど)。

⑥入力欄をクリアして、リストを表示

和訳:
tasks(①で定義されたため名称変更不可)という配列に、組み込み関数push()を使って新しいタスクnewTask(⑤で定義されたため名称変更不可)を追加し、変数taskInput(③で定義されたため名称変更不可)の組み込みプロパティvalueに空の文字列を代入して入力欄をクリアし、その後、ユーザーが定義した関数renderTasks(⑦で定義されたため名称変更不可)を呼び出してタスクリストを更新している。

説明と和訳

このコードは、新しいタスクを配列に追加し、その後、入力欄を空にし、タスクリストを更新しています。

詳しい解説

  1. tasks.push(newTask);
    • tasks(①で定義されたため名称変更不可)という配列に、push()という組み込み関数を使って、新しいタスク(newTask(⑤で定義されたため名称変更不可)オブジェクト)を追加しています。
    • push()は、配列の最後に新しい要素を追加するための関数です。tasksは、タスクを管理する配列です(tasksは名称変更不可)。
    • newTaskは既出なので名称変更不可です。
  2. taskInput.value = "";
    • taskInput(③で定義されたため名称変更不可)の組み込みプロパティvalueに空の文字列"")を代入して、入力欄をクリアしています。これで、ユーザーがタスクを入力した後、入力フィールドが空になります。
    • taskInput(③で定義されたため名称変更不可)はHTMLの**<input>タグ**の要素を指しています。この要素は、
    • **valueは組み込みプロパティで、名称は変更不可です。t
  3. renderTasks();
    • renderTasks()は、ユーザーが定義した関数で、画面上に最新のタスクリストを表示するために呼び出されます。タスクが追加された後、リストを再描画して更新します(renderTasksは⑦で定義されたため名称変更不可)。

⑦タスクを表示する関数

和訳:
renderTasks(ユーザー定義関数で、ここでは名称変更可能)は、タスクリストを再描画するための関数である。taskList(初登場)という変数に、組み込み関数document.getElementById('task-list')を使ってHTML内のid="task-list"を持つ要素(<ul id="task-list"></ul>)を取得し、その要素内部のHTMLにinnerHTML(組み込みプロパティで名称変更不可)を使って空の文字列を代入してリストの中身を一旦クリアしている。
※クリアのタイミングは、新しいタスクの追加、タスクの完了、タスクの削除が行われたとき

1. function renderTasks()の概要

  • この関数は、タスクリストをHTMLに表示する(レンダリングする)ためのものです。
  • 新しいタスクが追加されたり、既存のタスクが完了または削除された際に、この関数が呼び出され、タスクリストの内容を更新します。

※function 〇〇の〇〇は自由に名前を変えられる関数名
※ここで名前を変えたら⑥と⑬と⑭でも変更する必要あり

2. let taskList = document.getElementById('task-list');

  • let taskList
    • taskListという変数(名称変更可能だが、この箇所以降では変更不可)に、取得した<ul>要素(タスクリストの表示領域)を格納しています。
    • これにより、今後の処理でtaskListを使って、リストの内容を変更・更新できるようにしています。
  • document.getElementById('task-list')
     ◦getElementByIdは、documentの中の特定の要素を探すためのメソッドです。このため、必ずdocumentとセットで使わないと機能しません。
    • HTMLの<ul id="task-list"></ul>という要素をJavaScriptで取得しています。**id="task-list"**がつけられた<ul>タグは、ユーザーが追加したタスクリストを表示するための部分です。

    HTML側の該当部分:<ul id="task-list"></ul>

 ※let 〇〇の〇〇は自由に名前を変えられる変数名

3. taskList.innerHTML = "";

  • **taskList.innerHTML = "";**は、タスクリストの中身を一旦すべてクリアする操作です。
    • innerHTMLは、要素の内部のHTML内容を操作するためのプロパティです。ここで空文字列""を代入することで、<ul>タグ内のすべてのリストアイテム(<li>タグ)を一旦削除します。
    • タスクリストを更新する際に、古いリストが残らないように、一度リストを空にしてから新しい内容を追加していきます。


※function 〇〇、let 〇〇 の〇〇は自由に名前を決められるものが来ます。
※ドット記法の左側も基本的には自由に名前を決められるものが来ます。(thisなどの予約語が来ることもある)

入力系の要素(<input><textarea>など)でクリアしたい場合は、〇〇.value = ""
リストの要素(<ul><ol>など)でクリアしたい場合は、〇〇.innerHTML = ""

⑧タスクをリストに追加する

和訳例:
tasks(①で定義されたため名称変更不可)という配列に対して、forEach()(組み込み関数で名称変更不可)を使い、各タスクを順に処理しています。このとき、taskは、tasks配列の各要素(タスクオブジェクト)を指しています。このタスクオブジェクトは⑤で作成されたnewTaskオブジェクトです。task.textでは、taskオブジェクトのtextプロパティにアクセスするためにドット記法を使用しています。textContent(組み込みプロパティ)にtask.textを設定することで、リスト項目にタスクの内容を表示しています。

★ちょっと復習(ドット記法)

オブジェクト.プロパティ // プロパティ(固定された文字列のみ)にアクセスする場合
オブジェクト.メソッド() // メソッドを呼び出す場合

オブジェクト:ドット記法を使う対象となるデータのまとまり。
プロパティ:オブジェクトが持つデータや値。
メソッド:オブジェクトが持つ関数や機能(オブジェクト内で使える関数のこと)。

※プロパティとメソッドはオブジェクトとセットで初めて機能します。単体では使えません。

1. 全体の流れ

このコードは、タスク管理アプリの一部で、ユーザーが入力したタスクを画面にリスト形式で表示するために使われます。具体的には、tasksという配列(リスト)の中に保存されているタスク(やるべきこと)を、1つ1つ画面に表示する役割を果たしています。


2. tasks.forEach((task, index) => { ... }) の意味

  • **tasksは、これまでにユーザーが入力したタスクの一覧(配列)**です。
  • **forEach()**は、配列の中の要素を1つずつ取り出して処理するための関数です。ここでは、配列に保存されたタスク(task)を1つずつ処理しています。
  • **(task, index)は、配列の各要素とそのインデックス番号(順番)**を表しています。例えば、1番目のタスクがtaskに入り、その順番(index)も使えます。
  • indexは、新しいタスクの追加・タスクの完了・タスクの削除をする際には、index番号を使ってそのタスクを識別する必要があるため、重要になります。
和訳
tasksという配列の各要素であるtaskオブジェクトと、そのインデックス番号indexを使って順番に処理を行う。

3. let listItem = document.createElement('li');

  • **document.createElement('li')**は、HTMLのリスト項目タグ(<li>)をJavaScriptで新しく作成するという意味です。
    • **<li>**は、HTMLでリスト項目を表すタグで、リスト形式で物事を表示したいときに使います。
    • ここでは、新しいタスクを表示するために<li>タグを動的に作成しています。
和訳
listItemという変数に、組み込み関数document.createElementを使って新しい<li>タグ(リスト項目)を作成し、代入している。

4. listItem.textContent = task.text;

  • textContent: HTML要素のテキスト内容を取得または変更するための組み込みプロパティ。
  • listItem.textContentは、先ほど作成した<li>タグの中に表示するテキストの内容を設定します。
    • task.textには、ユーザーが入力したタスクのテキスト(やるべきことの内容)が入っています。例えば、「買い物に行く」や「メールを送る」といったものです。
    • **listItem.textContent = task.text;**とすることで、<li>タグの中にそのタスクの内容が表示されるようになります。
和訳
変数listItemの組み込みプロパティtextContentに、taskというオブジェクトのtextプロパティの値を代入している。

5. HTMLとの関係

このコードの目的は、JavaScriptで作成した新しい<li>タグを、HTMLのリストに追加して、画面にタスクを表示することです。HTMLのリストに項目が追加されると、画面に新しいタスクが表示されます。

  • JavaScriptでタグを作成。
  • そのタグに、ユーザーが入力したタスクのテキストをセット。
  • 最終的に、そのタグをHTMLのリストに追加することで、画面に表示される。

アロー関数のおさらい
tasks.forEach(function(task, index){ }
↓(アロー関数を使うと)
tasks.forEach((task, index) => { }
※アロー関数を使うとfunctionが省略されコードが短くなる

⑨タスクが完了しているかどうかを確認

和訳例:
もしtaskオブジェクトのcompletedプロパティ(⑤で定義されたプロパティで名称変更不可)がtrueなら、変数listItem(⑧で定義済みのため名称変更不可)の組み込みプロパティstyle.textDecorationに"line-through"を設定して、取り消し線を表示する。

if (task.completed):

  • task.completedは、taskオブジェクトの**completedプロパティ**を確認しています。
  • **completed**がtrueであれば(つまり、タスクが完了していれば)、次の処理が実行されます。
  • **completed**はユーザーが定義したプロパティ(⑤で定義されたプロパティで名称変更不可)であり、タスクが完了したかどうかを追跡しています。


listItem.style.textDecoration = "line-through";:

  • listItemstyleプロパティにアクセスし、textDecorationプロパティを設定しています。
    styleはHTML要素のCSSスタイルを設定または取得するための組み込みプロパティです。
    textDecorationは、文字の装飾を指定するための組み込みプロパティです。
    style.textDecorationは必ずセットで使います。
  • "line-through"という値は、文字に取り消し線を表示するためのスタイルです。
    style.textDecorationの代わりにtextContentを使うとlistItemの <li>~</li>の中に"line-through" という文字列が直接表示されます。取り消し線を引くことにはなりません

⑩タスクの完了状態を切り替える

和訳:
completeButtonという新しい変数に、組み込み関数document.createElement('button')を使って新しい<button>タグを作成し、そのボタンのtextContent(組み込みプロパティで名称変更不可)に「完了」というテキストを設定している。さらに、completeButton.onclick(組み込みプロパティで名称変更不可)には、ボタンがクリックされたときにcompleteTaskというユーザー定義の関数を呼び出して、指定されたタスクを完了としてマークする処理を設定している。completeButtonは名称変更可能だが、ここでは「完了ボタン」という意味で使用されている。

解説

  1. let completeButton = document.createElement('button');
    • completeButtonは、この行で新しく作成される変数です。この変数に、**document.createElement('button')**を使って、HTMLの<button>タグをプログラムで生成しています。
    • completeButtonは、新しく定義された変数で、ここでは名称を自由に変更可能です。たとえば、**completeBtnfinishButtonといった名前に変えることもできますが、ここでは「完了ボタン」という意味を持つcompleteButton**が使われています。
    • **createElement**は、組み込み関数で、HTML要素を作成するために使われます。名称は変更できません
  2. completeButton.textContent = "完了";
    • **textContent**は、組み込みプロパティです。作成したボタンのテキスト内容を設定するために使用されています。ここでは、ボタンの表示テキストを「完了」に設定しています。
    • textContentは名称変更不可ですが、ボタンのテキスト部分である**"完了"**は、自由に変更できます(例:"完了しました"などに変更可能)。
  3. completeButton.onclick = () => { completeTask(index); };
    • **onclickは、組み込みプロパティで、ボタンがクリックされたときに実行される処理を設定するために使われます。ここでは、ボタンがクリックされると、⑬で定義されているcompleteTask()**という関数が呼び出され、タスクが「完了」としてマークされます。
    • onclickは名称変更不可ですが、**completeTask()**はユーザー定義の関数なので、名称を変更することが可能です。⑬で定義されている関数です。
    • **indexは、tasks配列内でどのタスクを完了するかを示すインデックス(位置)です。このindex**はforEachで使われる引数なので、名称は変更可能ですが、ここでは一貫性のためそのまま使用しています。

⑪タスクを削除する処理

和訳:
deleteButtonという新しい変数に、組み込み関数document.createElement('button')を使って新しい<button>タグを作成し、そのボタンのtextContent(組み込みプロパティで名称変更不可)に「削除」というテキストを設定している。さらに、deleteButton.onclick(組み込みプロパティで名称変更不可)には、ボタンがクリックされたときにdeleteTaskというユーザー定義の関数(初登場)を呼び出して、指定されたタスクを削除する処理を設定している。

解説

  1. let deleteButton = document.createElement('button');
    • **deleteButtonという新しい変数に、document.createElement('button')**という組み込み関数を使って、新しい<button>タグを作成しています。
    • **deleteButtonは、ここで新しく定義された変数なので、名称は変更可能です。例えば、removeButtondeleteBtnに変更することができますが、ここでは削除ボタンという意味でdeleteButton**が使われています。
    • createElementは、HTML要素を生成する組み込み関数で、名称変更不可です。
  2. deleteButton.textContent = "削除";
    • textContentは、ボタンの表示内容を設定するための組み込みプロパティです。ここでは、ボタンに表示する文字を**「削除」**に設定しています。
    • **textContentは、HTML要素に表示するテキスト内容を指定するためのプロパティで、名称は変更できません。ただし、"削除"という表示文字自体は、自由に変更可能です。例えば、"消す""Remove"**などに変えることができます。
  3. deleteButton.onclick = () => { deleteTask(index); };
    • onclickは、ボタンがクリックされたときに実行される処理を設定する組み込みプロパティです。ここでは、削除ボタンがクリックされると、⑭で定義した**deleteTask()**という関数が呼び出され、そのタスクが削除されます。
    • **onclick**は、ボタンのクリックイベントを設定するためのプロパティで、名称は変更できません
    • **deleteTask()**は、ユーザーが定義した関数で、名称は変更可能ですが、ここでは削除処理に適した名前として使われています。⑭で定義されています。
    • **index**は、tasks配列内でどのタスクを削除するかを示す位置を表しており、変更可能ですが、ここでは一貫してそのまま使用されています。

⑫作成したボタンをtaskListに追加

和訳:
listItem(⑧で定義されたため名称変更不可)という変数に、「完了ボタン」であるcompleteButton(⑩で定義)と「削除ボタン」であるdeleteButton(⑪で定義)をそれぞれ追加し、最後に変数taskList(⑦で定義されたため名称変更不可)にlistItemを追加して、画面にタスクとボタンを表示する。

  1. listItem.appendChild(completeButton);
    • listItem(タスクのリスト項目)(⑧で定義された変数)の中に、completeButton(「完了ボタン」)(⑩で定義されたため名称変更不可)を追加しています。appendChild()は、指定した要素を親要素(ここではlistItem)に追加するための組み込み関数です。
    • listItemは⑧で定義されたため名称変更不可
  2. listItem.appendChild(deleteButton);
    • 同様に、listItem(⑧で定義された変数)の中にdeleteButton(「削除ボタン」)を追加しています。これで、1つのリスト項目に「完了ボタン」と「削除ボタン」の両方が含まれるようになります。
    • listItem(⑧で定義された変数)に、deleteButton(⑪で定義されたため名称変更不可)を子要素として追加しています。
  3. taskList.appendChild(listItem);
    • 最後に、taskList(⑦で定義された変数)というタスクリスト全体を表す要素(HTMLのid="task-list"を持つ要素)の中に、listItem(リスト項目)(⑧で定義された変数)を追加しています。これで、画面にタスクが表示され、そのタスクに「完了」ボタンと「削除」ボタンが表示されます。
    • ⑧で作成したlistItemの<li>~</li>を、この⑫でtaskListの<ul>~</ul>の下に追加しています。

⑬タスクの完了状態を切り替える

和訳:
completeTaskというユーザーが定義した関数は、引数として(index)を受け取り、その(index)を使ってtasks配列の[index]番目のタスクを参照し、そのタスクのcompletedプロパティ(⑤で定義されたため名称変更不可)を反転させる。そして、その後にユーザーが定義したrenderTasks関数を呼び出して、タスクリストを更新する。
※indexを受け取る場所は下にある「どこからindexが渡されるのか?」を参照

function completeTask(index)

  • この関数は、indexという引数を受け取ります。indexは、tasks配列の中のどのタスクが対象かを表しています。たとえば、tasks配列の3番目のタスクを操作したい場合、**index**は2(配列は0から始まるため)になります。
どこからindexが渡されるのか?
●completeButton.onclick(⑩)により、「完了」ボタンがクリックされたときにアロー関数が実行されます。

●**completeTask(index)がこのアロー関数内で呼び出されており(⑩)、その際にindex**が渡されます。
・indexは、tasks配列の中でタスクがどの位置にあるかを示すインデックス番号です。tasksの各タスクは配列の要素であり、それぞれにインデックス番号があります。
・例えば、tasks[0]が1番目のタスク、tasks[1]が2番目のタスクといった形で、indexはその番号を表しています。

●indexは、そのタスクの位置を表す数値として**completeTask()**関数に渡され、tasks[index]としてそのタスクを操作しています。

該当箇所:
⑧:tasks.forEach((task, index) => {...}) で、index がタスクのインデックスとして取得されます。
⑩:completeButton.onclick = () => { completeTask(index); } で、そのインデックスを completeTask 関数(⑬)に引数として渡しています。
⑬function completeTask(index) {
tasks[index].completed = !tasks[index].completed;
renderTasks();
}
つまりcompleteButtonが押されると
{ text: "国語の宿題をやる", completed: false } → { text: "国語の宿題をやる", completed: true }
という感じにタスクの完了状態をクリックするたびに反転させることができます。なのでもう一度completeButtonが押されるとcompleted: falseに戻ります。いわゆる**トグル(切り替え)**の役割を果たしています。
さらに⑨のコード
if (task.completed) {
listItem.style.textDecoration = "line-through";
}
これによって
国語の宿題をやる(タスクリストで取り消し線が表示される)
最後に⑦のコード
function renderTasks() {
let taskList = document.getElementById('task-list');
taskList.innerHTML = ""; // 一旦リストをクリア
まず、document.getElementById('task-list') が実行され、HTMLドキュメント内の id="task-list" を持つ <ul>要素を取得します。そして、taskList.innerHTML = "" によって、画面上のタスクリスト(リストのテキストデータ部分)を一旦すべてクリアします。これにより、リストが空になり、古い状態が消去されます。その取得した<ul>要素を使って再描画します。
取得(HTML要素(オブジェクト))→削除(リストのテキストデータ部分)→取得したデータを使って再描画

なぜこの順番が重要か:
・要素の取得が最初に必要:まず、document.getElementById('task-list') で <ul> 要素を取得しなければ、その要素に対して操作を行うことができません。そのため、最初に taskList に <ul> 要素を代入します。
・リストをクリアするために:次に taskList.innerHTML = "" を実行することで、リスト内のすべてのテキストデータが消去され、リストが空の状態にリセットされます。これは、リストを更新する前に古い内容を消去するために必要なステップです。
・取得した<ul>要素を使って再描画は⑧~⑫で行われています。
各部分の役割:
⑧:tasks 配列をループ(forEach())して、各タスクを表示します。ここで、タスクの内容(task.text)を基に新しい <li> 要素を作成しています。ここで全てのリスト(テキストデータ)が復活します。
⑨:タスクが完了している場合は、その復活したリストに取り消し線(textDecoration)を追加しています。task.completed の値によって、完了したタスクを視覚的に表現します。
⑩~⑪:それぞれ、完了ボタンと削除ボタンを作成し、各タスクに追加しています。これにより、タスクごとに操作ボタンが付与されます。
⑫:新しく作成された listItem(タスクを表示する <li> 要素)を、taskList に追加しています。この時点でタスクリストに新しい状態のタスクが反映されます。


tasks[index].completed = !tasks[index].completed;

  • tasks[index]は、tasks配列のindex番目にあるタスク(オブジェクト)を指しています。たとえば、indexが2なら、tasks[2]は3番目のタスクです。
  • tasks[index].completedは、そのタスクのcompletedプロパティ(⑤で定義されたため名称変更不可)を指しています。現在の値を!(否定演算子)で反転しています。
    • もしそのタスクが完了(true)していたら、未完了(false)に変更。
    • もしそのタスクが未完了(false)だったら、完了(true)に変更。
和訳:
tasks配列のindex番目にあるタスクのcompletedプロパティに、現在のcompletedプロパティの値を反転させた値を代入している。
※このコードは、タスクの完了状態を**トグル(切り替える)**する役割を果たしています。


renderTasks();

  • この関数は、タスクリストを画面に再表示するためのものです。タスクの完了状態が変わったあと、最新の状態を画面に反映させるために呼び出されています。
  • ユーザーが定義した関数です。(⑦で定義されたため名称変更不可)

⑭指定されたタスクの削除

和訳:
deleteTask(⑪で削除ボタンがクリックされたときに呼び出されるユーザー定義関数で、ここでは名称変更不可)というユーザーが定義した関数は、引数(index)を受け取り、tasks配列の[index]番目のタスクをsplice()という組み込み関数を使って削除し、その後にユーザーが定義したrenderTasks(⑦で定義されたため名称変更不可)関数を呼び出してタスクリストを更新する。

function deleteTask(index)

  • このユーザーが定義した関数deleteTaskは、引数(index)を受け取り、tasks配列の[index]番目のタスクを削除します。ここで、indexは削除したいタスクの位置(インデックス番号)を表します。


tasks.splice(index, 1);

  • splice()は、配列から要素を削除または追加する組み込み関数です。
  • **index**は、どの位置のタスクを削除するかを指定します。
  • 1は、削除する要素の数を表し、ここでは1つだけ削除します。つまり、index番目のタスクを1つ削除します。
  • 「国語の宿題」が完了した場合、インデックス番号を使ってリストから「国語の宿題」を削除します。


renderTasks();

  • この関数を呼び出して、削除されたタスクを反映した状態で、タスクリストを**再描画(更新)**します。ユーザーが定義した関数です。

splice()

splice() の構文

例:要素の追加を行う splice() の使い方

削除と追加を同時に行う例

主な組み込みプロパティの一覧

innerHTML

HTML要素の内部のコンテンツを取得または変更します。

length

文字列、配列、オブジェクトのプロパティの長さを返します。

・配列の長さを取得

・文字列の長さを取得

constructor

オブジェクトのコンストラクタを参照します。

prototype

オブジェクトや関数のプロトタイプチェーンを操作するために使用されます。

valueOf

オブジェクトのプリミティブ値を返します。基本的にはオブジェクトが表す値そのものを取得するために使います。

toString

オブジェクトを文字列に変換します。

hasOwnProperty

オブジェクトが指定したプロパティを自分自身のプロパティとして持っているかどうかを確認します。

isPrototypeOf

オブジェクトが別のオブジェクトのプロトタイプチェーンに存在するかを確認します。

charAt

文字列の指定した位置にある文字を返します。

slice

文字列や配列の一部を新しい文字列や配列として返します。

・文字列のスライス

・配列のスライス

push

配列の末尾に新しい要素を追加します。

pop

配列の末尾から要素を削除し、その要素を返します。

shift

配列の先頭から要素を削除し、その要素を返します。

unshift

配列の先頭に新しい要素を追加します。

includes

配列や文字列が特定の要素を含んでいるかどうかを確認します。

・配列のincludes

・文字列のincludes

concat

2つ以上の配列や文字列を結合して新しい配列や文字列を返します。

・配列のconcat

・文字列のconcat

keys

オブジェクトのプロパティ名の配列を返します。

組み込みプロパティの例の範囲

  1. 文字列(String)
    • length: 文字列の長さを返す。
    • charAt(): 指定した位置の文字を返す。
    • includes(): 文字列に特定の部分文字列が含まれているか確認する。
    • さらに、endsWith()startsWith()などの文字列操作に関連するプロパティもあります。
  2. 配列(Array)
    • length: 配列の長さを返す。
    • push(): 配列の末尾に要素を追加。
    • pop(): 配列の末尾から要素を削除。
    • 他にも、splice()join()など、多くの配列操作に関するプロパティが存在します。
  3. オブジェクト(Object)
    • prototype: オブジェクトのプロトタイプを操作するためのプロパティ。
    • constructor: オブジェクトのコンストラクタを参照する。
    • 他にも、Object.getOwnPropertyNames()Object.defineProperty()など、オブジェクト操作に関する多くのプロパティがあります。
  4. その他のデータ型やオブジェクト
    • Date: 日付や時刻を操作するための多くのプロパティがある。
    • Math: 数学的な定数や関数に関するプロパティ。
    • textContent: HTML要素のテキスト内容を取得または変更するためのプロパティ。
    • **windowdocument**のようなブラウザ環境に特有のプロパティも多数存在します。

さらに詳細なプロパティの例

  • Array.prototype.map(): 配列の各要素に関数を適用し、新しい配列を返す。
  • String.prototype.toUpperCase(): 文字列を大文字に変換する。
  • Object.prototype.toString(): オブジェクトの文字列表現を返す。

もっと多くの組み込みプロパティが存在

JavaScriptは多くのビルトインオブジェクトやデータ型に対して、豊富なプロパティを提供しています。これには、例えば次のようなプロパティも含まれます。

  • Array.isArray(): 配列かどうかを確認するためのメソッド。
  • String.prototype.match(): 正規表現を使って文字列を検索する。
  • Object.freeze(): オブジェクトを変更不可能にする。

まとめ

これまでに挙げたプロパティは、JavaScriptの主な組み込みプロパティの一部ですが、実際にはさらに多くのプロパティが存在します。JavaScriptは非常に柔軟で、さまざまなデータ型やオブジェクトに対して、数多くの組み込みプロパティが用意されています。

本日の感想

コードの解読に4.5日近くかかってしまった。いくら土日をはさんだとはいえかかりすぎです。しかもコードの解読が終わっただけなので実際にアプリを作るのはこれからです。なにかを理解するのに人一倍時間がかかるのが本当に悩みです。でも最初は何でもスピードなんて出ないものです。ということを自分に言い聞かせて頑張ります。これからアプリづくりを始めます。

ここに初めて来た人はゼヒ0日目を読んでください。プログラミング知識0のおじさんがお金持ちになるまでのプランと熱い思いが載っています。私と一緒に運要素を排除したゴリゴリの脳筋プレイでお金持ちを目指しませんか?

0日目の記事はこちら
お金持ちまでの道のり:0日目

コメント

タイトルとURLをコピーしました