【脱jQuery】重複したHTML要素を削除するプログラムをJavaScriptで書き直す
目次

今回のブログはjQueryで書いたプログラムをJavaScriptで書き直すという作業を行いました。その時の記録を残すため、ブログを書いていきたいと思います。今回題材にするプログラムは、重複したHTML要素を削除するというプログラムです。JavaScriptの普段使いできるテクニックも書いているため、JavaScriptをもっと勉強したいという方にも参考になると思います。
jQueryで重複したHTMLを削除する
今回題材にするのは重複したHTML要素を削除するプログラムです。
エントリー毎にコピーライトを設定し、一覧ページでコピーライトを一括表示したいが、同じコピーライトが重複するのは避けたいという場合など、使える場面は多々あるのではないかと思います。
↑のようにjQueryを書くと、重複したHTML要素を削除できます。実際にHTML上では <li>
という要素が3つ並んでいますが、ブラウザ表示の方では、"おはようございます"というテキストが1つになっています。
おはようございます</li>
今回はこのプログラムを題材に【脱jQuery】を目指して、JavaScriptに書き直していきたいと思います。
JavaScriptでリプレイスする
JavaScriptでリプレイスするにあたって、今回以下の2通りの方法があります。
for‥of
を使用する方法Array.prototype.reduce
を使用する方法
今回はこの2通り紹介していきます。
for…of を使用する
for…of
を使用したプログラムは下記になります
こちら順番に解説します。
ます、↓のコードを見てください。
const texts = new Set();
texts
という変数に 空の Set
オブジェクトを代入しています。Set
オブジェクトとはなんぞや?という方はコチラの記事を参考にしてみていただけると幸いです。簡単に言うと、重複した値がない配列です。
for (let li of document.querySelectorAll(".txt_list li")) {
for…of
という構文を使用しています。for…of
を使用することでDOMコレクションにおいて繰り返し処理を行うことができます。
ちなみに、JavaScriptにおいて、形の似ているfor…in
という構文があると思いますが、for…of
と for…in
の違いは繰り返しの対象が、値かプロパティという違いになります。for…of
が値の繰り返しで、 for…in
がプロパティの繰り返しです。
const string = li.textContent;
ここでは、 string
という変数に li
の textContent
を代入しています。つまり、現在ループ対象の <li>
タグ内のテキストを取得しています。1度目のループの場合は"こんにちは"、2度めの場合は"おはようございます"が string
に代入されます。
texts.has(string) ? li.remove() : texts.add(string);
この行では三項演算子を用いて、記述しています。has
メソッドや add
メソッドは Set
オブジェクトのメソッドになります。Set
オブジェクトに string
があれば、現在ループ対象の li
を削除し、なければ、Set
オブジェクトに string
を追加します。
Array.prototype.reduce を使用する
次に、Array.prototype.reduce
を使用する方法を説明します。Array.prototype.reduce
についての説明は、コチラの記事がわかりやすかったので、リンクを張っておきます。
まずは、コードを見てください。
こちら順番に解説します。
ます、↓のコードを見てください。
[...document.querySelectorAll(".txt_list li")].reduce(
この書き方をすることで、 document.querySelectorAll(".txt_list li")
で取得するとオブジェクトととして取得されてしまう document.querySelectorAll
メソッドですが、配列として li
タグを取得することができます。配列で取得することで reduce
メソッドを使用することができるようになります。
(prev, currnet) =>
prev.has(currnet.textContent)
? (currnet.remove(), prev)
: prev.add(currnet.textContent)
この行では三項演算子を用いて、ほとんど for…of
のときと同じことをしています。しかし、このコードではポイントが2つあります。
1つ目は (currnet.remove(), prev)
を()で囲っている部分です。JavaScriptでは、括弧の中がカンマ演算子で列挙された場合は、括弧内を左から右に評価し、最後の部分が評価され返るという仕様があります。演算子のため()で囲まれています。
そのため、 current.remove()
が評価された後に、prev
を戻り値として返しています。
カンマ演算子についての説明はMDNを参考にしてください。
2つ目は (currnet.remove(), prev)
で prev
を返している点です。この prev
がないとエラーになります。これは、reduce()
メソッドで「2回目以降のコールバック呼び出しの第1引数には前回のループで return した値が代入される」という仕様が存在するため、remove()
という処理のみではなく、 prev
を return
しています。
これら2つの仕様は、JavaScript中級者を目指す上で大切な部分になってくると思います。難しいところですが、この機会に理解しておきましょう。
new Set()
最後に、上記の部分です。これは Set
オブジェクトの宣言と、 reduce()
メソッドの第2引数に Set
オブジェクトを与えています。 reduce()
メソッドの第2引数は初期値の役割をしており、第1引数のコールバックの第1引数に代入されます(ループ1周目のみ)。
まとめ
今回の要点をまとめると…
以上になります。これからもJavaScriptを極めるため日々勉強に励んでいきたいと思います。この記事を読んでくれた皆様、ありがとうございました。