

→この記事を参照
★ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
//ーーーーーーーーーーーーーーーーーー // 変数(定数)定義 //ーーーーーーーーーーーーーーーーーー const addTask = document.querySelector('add'); const list = document.querySelector('.todos'); const search = document.querySelector('.search input'); //ーーーーーーーーーーーーーーーーーー // 関数定義 //ーーーーーーーーーーーーーーーーーー //タスク追加 const createTodoList = task => { // HTMLテンプレートを生成 const html = ' <li class="list-group-item d-flex justify-content-between align-items-center"> <span>${task}</span> <i class="far fa-trash-alt delete"></i> </li> '; list.innerHTML += html; } //フィルタリング機能 const filterTasks = (term) => { Array.from(list.children) //フィルタ条件 .filter((todo) => !todo.textContent.toLowerCase().includes(term)) .forEach((todo) => todo.classList.add('filtered')); Array.from(list.children) .filter((todo) => todo.textContent.toLowerCase().includes(term)) .forEach((todo) => todo.classList.remove('filtered')); }; //即時関数により、スコープ内で処理を実行 (function(){ //初期化処理 //ローカルストレージに格納されている値を取得し、リストを生成する for(var key in localStorage){ var html = localStorage.getItem(key); if (html){ list.innerHTML += localStorage.getItem(key); } } })(); const saveTaskLocalStorage = (task, html) => { // nullは、localStorageに保存しない if(html){ localStorage.setItem(task, html); return; } return; } const deleteTaskFromLocalStorage = task => { localStorage.removeItem(task); return; } //ーーーーーーーーーーーーーーーーーー //イベントの設定 //ーーーーーーーーーーーーーーーーーー //タスク追加 addTask.addEventListener('submit', e => { //デフォルトのイベントを無効 e.preventDefault(); //タスクに入力した値を、空白を除外して格納 const task = addTask.add.value.trim(); if(task.length) { // Todo ListのHTMLを作成 createTodoList(task); // タスクに入力した文字をクリア addTask.reset(); } }); //削除機能 list.addEventListener('click', e => { if (e.target.classList.contains('delete')){ e.target.parentElement.remove(); } }); //フィルタリング機能 search.addEventListener('keyup', () => { //空白削除かつ、小文字に変換(大文字・小文字の区別をなくす) const term = search.value.trim().toLowerCase(); filterTasks(term); }); |
本編メモ
①タスク追加②削除
③フィルタリング(検索?)
String.prototype.trim()
trim() メソッドは、文字列の両端の空白を削除します。このコンテクストでの空白には、空白文字(スペースやタブ、ノーブレークスペースなど)とすべての改行文字(LF や CR など)を含みます。
1 2 3 4 5 |
const greeting = ' Hello world! '; console.log(greeting); // expected output: " Hello world! "; console.log(greeting.trim()); // expected output: "Hello world!"; |
Element.classList は読み取り専用のプロパティで、生きた DOMTokenList コレクションでその要素の class 属性を返します。これを使用してクラスリストを操作することができます。
classList を使用することは、 element.className から取得した空白区切りの文字列として要素のクラスのリストにアクセスすることの便利な代替手段になります。
const elementClasses = elementNodeReference.classList;


classListとは、対象要素に設定しているクラスを配列のように扱えるオブジェクトです。add(追加)やremove(削除)やreplace(置き換え)などのメソッドがあります。
→classList は大変便利で、要素に設定されているクラスをリスト(配列)で取得できる。
●classListの主なメソッド
・add( className ) : クラスを追加
・remove( className ) : クラスを削除
・toggle( className ) : クラスがあれば削除・無ければ追加
・contains( className ) : クラス名の有無を true / false で返す
・replace( oldClass, newClass ): oldClassをnewClassで置き換え
JavaScript の Array オブジェクトは、配列を構築するためのグローバルオブジェクトで、配列とは複数の要素の集合を格納管理するリスト構造です。
●説明
配列は、リストのようなオブジェクトであり、配列に対して横断的な操作や変更を行う組み込みのメソッドを持ちます。JavaScript の配列は、要素数も要素の型も固定されていません。配列のサイズは常に可変であり、データを連続しない位置に格納できるため、JavaScript の配列は密であることが保証されていません (プログラマの使い方次第です)。一般に、これらは便利な特性ではありますが、固定された配列が必要であれば、Typed Array の使用を検討するのも良いでしょう。
●配列要素へのアクセス
JavaScript の配列のインデックスは 0 から始まるので、配列の最初の要素はインデックス 0 にあります。そして、最後の要素のインデックスは length プロパティの値から 1 を引いた値になります。不正なインデックス番号を使った場合は undefined を返します。
●メソッド
・Array.from()
配列型 (array-like) や反復型 (iterable) オブジェクトから、新しい Array インスタンスを生成します。
・Array.isArray()
配列であれば true を、配列でなければ false を返します。
・Array.of()
可変個の引数から新しい Array インスタンスを生成します。引数の数や型による特別処理はありません。
forEach() メソッドは与えられた関数を、配列の各要素に対して一度ずつ実行します。
●構文
arr.forEach(callback(currentValue [, index [, array]])[, thisArg]);
・callback;各要素に対して実行するコールバック関数で、3つの引数をとります。
→currentValue:現在処理されている配列の要素です。
→index:現在処理されている配列の要素のインデックスです。
→array:forEach() が呼び出されている配列です。
・thisArg:callback 内で this として使用する値です。
Array.from() メソッドは、配列風オブジェクトや反復可能オブジェクトから、新しい、浅いコピーの Array インスタンスを生成します。
●構文
Array.from(arrayLike[, mapFn[, thisArg]])
・arrayLike:配列に変換する配列風オブジェクトまたは反復可能オブジェクト
・mapFn:配列のすべての要素に対して呼び出される Map 関数。
・thisArg:mapFn を実行する時に this として使用する値。


JavaScriptにおいて、配列を処理するのに何を使おうかなと思って調べてみると、JavaScriptの繰り返し処理には「for」「for-in」「for-of」「Array.forEach」「jQuery.each」と色々あるようです。
配列の処理なので「Array.forEach」と「jQuery.each」どちらが良いか比較してみました。
●Array.forEach
構文:array.forEach(callback[, thisObj]);
・callback 各要素に対して実行するコールバック関数で、3つの引数をとります。
→value 現在処理されている配列の要素
→index 現在処理されている配列の要素のインデックス
→array forEachが適用されている配列
・thisObj 任意。callback 内で this として使用する値
●jQuery.each($.each)
構文:jQuery.each(object, callback);
・object 繰り返しの対象となるオブジェクト
・callback 各要素に対して実行するコールバック関数で、2つの引数をとります。
→index 現在処理されている配列の要素のインデックス
→value 現在処理されている配列の要素
●まとめ
「jQuery.each」はもちろん「jQuery」が使用できる環境でないと使えないというデメリットはありますが、「Array.forEach」より使い勝手は良いような気がします。
コールバック関数の順序が違ったり、thisの扱いが違ったり、ループから抜ける際の違いがあったりと、それぞれの違いを分かった上で使い分けたいですね。
④js文法
●アロー関数とは
関数式にはfunctionキーワードを使った方法以外に、Arrow Functionと呼ばれる書き方があります。 名前のとおり矢印のような=>(イコールと大なり記号)を使い、匿名関数を定義する構文です。 次のように、functionキーワードを使った関数式とよく似た書き方をします。
→アロー関数は、匿名関数を記述するもの。
Arrow Functionには書き方にいくつかのパターンがありますが、functionキーワードに比べて短く書けるようになっています。
1 2 3 4 5 6 |
// Arrow Functionを使った関数定義 const 関数名 = () => { // 関数を呼び出したときの処理 // ... return 関数の返す値; }; |
●アロー関数の省略記法
Arrow Functionには省略記法があり、次の場合にはさらに短く書けます。
・関数の仮引数が1つのときは()を省略できる
・関数の処理が1つの式である場合に、ブロックとreturn文を省略できる
(その式の評価結果をreturnの返り値とする)
1 2 3 4 5 6 7 8 9 |
// 仮引数の数と定義 const fnA = () => { /* 仮引数がないとき */ }; const fnB = (x) => { /* 仮引数が1つのみのとき */ }; const fnC = x => { /* 仮引数が1つのみのときは()を省略可能 */ }; const fnD = (x, y) => { /* 仮引数が複数のとき */ }; // 値の返し方 // 次の2つの定義は同じ意味となる const mulA = x => { return x * x; }; // ブロックの中でreturn const mulB = x => x * x; // 1行のみの場合はreturnとブロックを省略できる |
●アロー関数と通常の関数の違い
Arrow Functionはfunctionキーワードの関数式に比べて、できることとできないことがはっきりしています。 たとえば、functionキーワードでは非推奨としていたarguments変数を参照できますが、Arrow Functionでは参照できなくなっています。 Arrow Functionでは、人による解釈や実装の違いが生まれにくくなります。
また、functionキーワードとArrow Functionの大きな違いとして、thisという特殊なキーワードに関する挙動の違いがあります。 thisについては「関数とスコープ」の章で解説しますが、Arrow Functionではこのthisの問題の多くを解決できるという利点があります。そのため、Arrow Functionで問題ない場合はArrow Functionで書き、そうでない場合はfunctionキーワードを使うことを推奨します。
関数式とは、関数を値として変数へ代入している式のことを言います。 関数宣言は文でしたが、関数式では関数を値として扱っています。 これは、文字列や数値などの変数宣言と同じ定義方法です。
1 2 3 4 5 6 |
// 関数式 const 関数名 = function() { // 関数を呼び出したときの処理 // ... return 関数の返り値; }; |
「addEventListener()」は、JavaScriptからさまざまなイベント処理を実行することができるメソッドになります。
●3種類の関数設定方法について
「addEventListener()」を記述する方法として、3種類の関数を設定する書き方があるのでまとめて解説をしておきます!
1つ目は、外部の関数を設定する方法です。この方法は、「sampleEvent()」という関数をイベント処理の外側で定義しているのがポイントです。関数内の処理が複雑であったり、ファイルが複数に分割されている場合などに使われるのが一般的です。
対象要素.addEventListener(種類, sampleEvent, false);
1 2 3 |
function sampleEvent() { //ここに処理を記述する } |
2つ目は、無名関数を設定する方法です。この方法が一般的によく使われる書き方になるでしょう。特徴としては、第2引数へそのまま関数を記述しているのがポイントです。単純な処理しか記述しないようなケースでは、関数を別で用意するよりもコードが分かりやすくなります。
1 2 3 |
対象要素.addEventListener(種類, function() { //ここに処理を記述する }, false); |
3つ目は、アロー関数を設定する方法です。こちらは、先ほどの無名関数をES2015の書き方にしたパターンなので、特徴的には同じになります。
1 2 3 |
対象要素.addEventListener(種類, () => { //ここに処理を記述する }); |
即時実行関数(IIFE, Immediately-Invoked Function Expression)は、 グローバルスコープの汚染を避けるために生まれたイディオムです。次のように、匿名関数を宣言した直後に呼び出すことで、任意の処理を関数のスコープに閉じて実行できます。 関数スコープを作ることでfoo変数は匿名関数の外側からはアクセスできません。
1 2 3 4 5 6 7 8 |
// 匿名関数を宣言 + 実行を同時に行っている (function() { // 関数のスコープ内でfoo変数を宣言している var foo = "foo"; console.log(foo); // => "foo" })(); // foo変数のスコープ外 console.log(typeof foo === "undefined"); // => true |
関数を式として定義して、そのまま呼び出しています。 functionからはじまってしまうとJavaScriptエンジンが関数宣言と解釈してしまうため、無害なカッコなどで囲んで関数式として解釈させるのが特徴的な記法です。これは次のように書いた場合と意味は同じですが、匿名関数を定義して実行するため短く書くことができ、余計な関数定義がグローバルスコープに残りません。
1 2 3 4 5 6 7 |
function fn() { var foo = "foo"; console.log(foo); // => "foo" } fn(); // foo変数のスコープ外 console.log(typeof foo === "undefined"); // => true |
ECMAScript 5までは、変数を宣言する方法はvarしか存在しません。 即時実行関数はvarによるグローバルスコープの汚染を防ぐために必要でした。しかしECMAScript 2015で導入されたletとconstにより、ブロックスコープに対して変数宣言できるようになりました。 そのため、グローバルスコープの汚染を防ぐための即時実行関数は不要です。 先ほどの即時実行関数は次のようにletやconstとブロックスコープで置き換えられます。
localStorage プロパティはローカルの Storage オブジェクトにアクセスすることができます。
localStorageまたはsessionStorageに保存されるデータはそのページのプロトコル固有であることに注意する必要があります。
Web Storage API の Storage インターフェイスは、特定のドメインのセッションストレージまたはローカルストレージへのアクセス機能を提供して、例えば保存されているデータアイテムを追加、変更、削除することができます。
ドメインのセッションストレージを操作したい場合は、Window.sessionStorage メソッドを呼び出してください。ドメインのローカルストレージを操作したい場合は、Window.localStorage を呼び出してください。
●メソッド
Storage.getItem()
キーの名称を渡すと、キーに対する値を返します。
Storage.setItem()
キーの名称と値を渡すと、ストレージにキーを追加する、または既存のキーに対する値を更新します。
Storage.removeItem()
キーの名称を渡すと、ストレージからキーを削除します。
Storage.clear()
このメソッドを呼び出すと、ストレージからすべてのキーを消去します。
Storage.key()
このメソッドは数値 n を渡すと、ストレージ内で n 番目のキーの名称を返します。
LocalStrageとは、JavaScriptでデータをブラウザに保存する仕組みです。同様な仕組みにSessionStrageやcookieがありますが、以下のような違いがあります。
→LocalStrageは保持期限が無制限だが、SessionStrageの保持期限はブラウザを閉じるまで
LocalStrageに値を保存するには以下のように記述します。「キー」には任意の文字列を指定します。
1 |
localStorage.setItem('キー', 値) |
値を読み込むには以下のように記述します。
1 |
localStorage.getItem('キー') |
→localStorage は、key value 形式でブラウザ上に情報を保持する。
この記事へのコメントはありません。