subtitle

RaiseTechの各種コースをはじめとしたイロイロな学習の記録

JavaScriptでToDoアプリを作る①

RaiseTechのReactコースの第4週目の課題。(すでに1週間遅れてるww)

お題は、「CodeSandboxを使用して、JavaScript/HTML/CSSでToDoアプリを作る」こと。


ヤバイヤバイ。

丸腰だから意味不明ww

何はともあれ、ググる。ググれ。ググろ。


とりあえず、アプリっぽいものができたので、丸腰の人が調べながらやった過程を記録。(8時間くらいかかったww)



ざっくりとやったことの流れ

  1. ToDoリストについて考えてみた(どんな機能があるか?)
  2. アイコン作った(ネコにしたかったw)
  3. Webの中の人のToDoリストを色々見てみた(機能的にまねできそうなところを探す)
  4. ToDoリストのデザインを考えた
  5. 同じことをやっていそうな人を探して、実装方法を参考にした
  6. CSSについてあまりよくわかってないことに気づき調べた
  7. CodeSandbox上で動作確認していたら、イベント発火しなくて2~3時間無駄にするw(別のブラウザ立ち上げて普通に動作確認したら、問題なかったというオチ)
  8. 概ね実装できたので、後は見た目をこねこね
  9. ToDoアプリっぽいのができて、とりあえず満足する



準備

まず、JavaScriptの前に、HTMLとCSSがわからないとお話しにならない。

HTMLはふわっとわかったつもりになっているが、CSSがよくわからないので、使いそうなところを簡単に調べる。


CSSまとめ


CodeSandboxの準備

CodeSandboxは、前に使ってみたので、環境の準備はOK。


準備はこのくらいかな。

あとは、とりあえず書いてみて、動かしてみて、試してみて、まず手を動かすのが一番早い。



出来上がりイメージ

これすごく大事。

イメージがないと、何も始まらない。

デザインとか、機能とか、まず妄想することが大事。

こういう感じ。(これは出来上がった画面だが、実際は各パーツを線で描いてみる程度)


機能

  • テキストボックスに入力した「やること」をやることリストに追加
  • やることリストの各項目の削除
  • やることリストの各項目の完了



アイコン作る

ネコアイコンとニッキューアイコン作成w

高級なイラレとかPhotoshopとかはないので、Windows標準ペイントツールを使うが、背景が透過にならず、時間を浪費ww

普通のペイントは背景が透過にならないらしい!(キィィ!)

結局これもWindows標準だが、ペイント3Dで透過にした。



イメージに沿うようにHTMLを書く

これはそんなに難しくない。

静的に作りたいイメージをHTMLで書いていくだけ。


HTML

<html lang="">
  <head>
    <meta charset="UTF-8"></meta>
    <title>ToDo List</title>
    <link href="src/styles.css" rel="stylesheet"></link>
  </head>

  <body>
    <h1>ToDo List</h1>
    <div class="flex">
      <img alt="ネコアイコン" src="pics/neco_icon.png" title="ネコ" width="10%" />
      <form class="">
        <input class="task_input" type="text" />
        <button class="task_submit" type="button">やること追加</button>
      </form>
    </div>
    <div id="table">
      <h2>やることリスト</h2>
      <ul class="task_list"></ul>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>


出来上がりイメージ



JavaScriptで動的な部分を作っていく

ここが一番苦労した。

だって、予備知識なしからのスタートだから!!


getElementsByClassName

document.getElementsByClassName('task_input')[0];

と書くことで、引数(task_input)で指定されたクラス名を持つ、最初の要素を取得できる。


console.log() で出力してみるとわかりやすい。

要素が取得できていることがわかる。

これ、[0] がポイントで、[0] がないと、HTMLCollectionがドロドロ出てきてヤバイ。(語彙ww)


[0] つけないと、こういう情報が取れる。


addEventListener

これは、the JavaScriptの動的なやつって感じ。

EventTarget.addEventListener(対象とするイベントの種類, 処理したい関数);

第3引数はオプションなので、ここでは説明を省略。


今回は、「やること追加」ボタンを押されたら、やりたいことを第2引数にする。


JavaScript

taskSubmit.addEventListener('click', evt => {
  evt.preventDefault();
  const task = taskInput.value;

  if (task === '') {
    window.alert('タスクを入力してください');
    return;
  }

  addTasks(task);

  taskInput.value = '';
});


追加したいやることリストに何も入力されていない状態で、「やること追加」ボタンを押されたときに、エラーを表示する。



追加したいタスクがある場合は、addTask()関数をCallする。


createElement

document.createElement('li');

引数で指定した要素を作成する。

HTMLでは、ul要素までしか作っていないので、その中身の<li></li>要素をJavaScriptで作っていく。


appendChild

Node.appendChild(親ノードに追加する子ノード(要素));

特定の親ノード(li)の下に、追加したいタスクとDelete、Completeボタンを追加。


JavaScript

const addTasks = (task) => {
  const listItem = document.createElement('li');
  const showItem = taskList.appendChild(listItem);
  showItem.innerHTML = task;

  const deleteButton = document.createElement('button');
  deleteButton.className = 'task_button';
  deleteButton.innerHTML = 'Delete';
  listItem.appendChild(deleteButton);

  const completeButton = document.createElement('button');
  completeButton.className = 'task_button';
  completeButton.innerHTML = 'Complete';
  listItem.appendChild(completeButton);

  deleteButton.addEventListener('click', (evt) => {
    evt.preventDefault();
    deleteTasks(deleteButton);
  });

  completeButton.addEventListener('click', (evt) => {
    evt.preventDefault();
    completeTasks(completeButton);
  });

  console.log(showItem);
};


ここまでが、やることリストを作る作業。

次に、追加されたリストを削除する処理を作る。


closest

Element.closest(要素);

指定したセレクタ(要素)に一番近い要素を指定する。


classList

Element.classList.add(要素);

指定した要素のclass属性を追加する。


Element.classList.remove(要素);

指定した要素のclass属性を削除する。


removeChild

Node.removeChild(子ノード);

子ノードを取り除く。

今回の場合は、Deleteボタンを押されたときに、該当のタスクを削除する。

あとは、Completeボタンが押されたら、もうこのボタンは必要なくなるので、Completeボタンの削除をしている。


JavaScript

const deleteTasks = (deleteButton) => {
  const chosenTask = deleteButton.closest('li');
  taskList.removeChild(chosenTask);
};

const completeTasks = (completeButton) => {
  const chosenTask = completeButton.closest('li');
  chosenTask.classList.add('complete');
  chosenTask.removeChild(completeButton);
};



CSSで見た目を整える

ここまでで、概ね実装は完了。

あとは、CSSで見た目を少し整える。


リストのアイコンはニッキュー画像で

CSS

ul li {
  background: url(../pics/pow_icon.png) no-repeat 0 0;
  background-size: auto 20px;
  padding-left: 30px;
}


肉球画像は、20px*20pxで作成。

背景として設定している。


リストの文字列は折り返す

CSS

li {
  margin: 2rem 3rem 2rem 1rem;
  word-break: break-all;
}


word-break: break-all; で、やることリストの文字列を折り返すことができる。


完了済のタスクはグレー文字色で取り消し線

CSS

.complete {
  text-decoration: line-through;
  color: #c0c0c0;
}


このくらいかな~。


あとは、このToDoリストは、ブラウザをリロードすると消えてしまうので、それを保持できるように検討する必要がある。

それは次回にして、今回はここまで。





今回までのToDoアプリはここで確認できます。

https://srzhb.csb.app/