バートリーのさいとうです。
今回は
【JavaScript】NodeListとかいうやつを配列に置き換えると、JSと仲良くなれそう
というテーマで、最近よく出てくるこやつと仲良くなった、という話をしていきます。
結論から申し上げると、JSのNodeListを配列に置き換えることができることで、弄れるようになりますよね〜っていうことを伝える記事になります。
なので、初心者向けの記事となります。
- NodeListと配列の違いとは?
- NodeList、配列で配列で出来ること、出来ないこと
- NodeListを配列に置き換える方法
あたりを、最近の実務からの学びとして共有しようと思いますので
上のいずれかを理解したいと思った方は、一緒に勉強していきましょう。あと、HTMLCollectionについても少し触れます。
NodeListと配列の違いとは
まずは公式から見ていきましょう。
NodeList
オブジェクトはノードの集合であり、Node.childNodes
などのプロパティやdocument.querySelectorAll()
などのメソッドの返値として用いられます。
なるほど、ノードと呼ばれるものの集合みたいです。Nodeとは何かを深ぼると非常に抽象度が増すので、ここでは説明しません。
いったん、querySelectorAllとかNode.childNodesを利用した時に返ってくる値の型のことだと思ってください。
このNodeListには特徴があります。
- forEachを利用可能
- 配列に利用できるmapなどのメソッドは利用できない。
つまり、配列に対して利用できるメソッドを利用することができない代わりにforEachを利用することができます。
対して配列は、forEachも使えて配列メソッドも利用できます。便利。ただ、DOMから取得する時に配列で取得することはできません。つまり、getElementByxxxxx系とか、queryxxxxxxx系のメソッドで、配列が返って来ることはありません。
ちなみに、HTMLCollectionというものもあります。これは、getElementsByClassNameやElementChildrenなどを利用した時に帰ってくるときの値の型です。
HTMLCollectionは配列のメソッドは利用できず、かつforEachも利用できません。
じゃあ何が出来るん…と思った方はとてもわかりやすかったので、こちらの記事をご覧ください。(この記事でも後述します。)
NodeListを配列に置き換える方法
では次に、NodeList(HTMLCollection)を配列に置き換える方法を見ていきます。
非常に簡単です。
let nodeList = document.querySelectorAll("samples")
let nodeListToArray = Array.from(nodeLIst)
これで完了です。Array.fromの引数に渡してあげて、それを変数に代入するだけです。
実際の様子を、メールアドレスの重複チェックをしたい時に実際に書いたコードを参照しながら見てみましょう。
例:メールアドレスの重複チェック
let nodeEmails = document.getElementsByName("samples[samples][][email]")
console.log(nodeEmails)
let arrayEmails = Array.from(nodeEmails)
console.log(arrayEmails)
このようにNodeListを返すgetElementsByNameを利用してフォームの値を全て取得し、それらをArray.fromで配列に置き換えます。
そうすると、出力の結果は以下の通りになります。
#NodeList
NodeList(2) [input#samples_samples_email.string.email, input#samples_samples_email.string.email]
#配列変換後
(2) [input#samples_samples_email.string.email, input#samples_samples_email.string.email]
違いはNodeListと明記されているかどうかです。
NodeListで返ってくる値も一見配列のように見えますが、このままでは配列に対するメソッドが利用できません。
このように配列にした後に、配列メソッドであるmapメソッドを利用して実際に入力されたメールアドレスをゴニョゴニョすれば重複チェックが可能です。以下コード。
let nodeEmails = document.getElementsByName("samples[samples][][email]")
let arrayEmails = Array.from(nodeEmails)
let checkEmails =arrayEmails.map(email => email.value)
nonDplCheckEmails = new Set(checkEmails)
if(checkEmails.length != nonDplCheckEmails.size){
alert("メールアドレスが重複しています。")
return false
}
実際の利用場面では、最後にreturn falseで返しているので、onclickとか定義してあげてくださいね。
補足:HTMLCollectionとNodeListの違いについて
先ほど触れたHTMLCollection何出来るん?の件について
HTMLCollectionは、NodeListと比較されます。比較される点は、動的か、静的かです。
- NodeList => 静的
- HTMLCollection => 動的
静的と動的の違いについては、こちらの記事を参考にすると
- 静的=DOMに変更があった時でも、取得されたDOMは変更されない。
- 動的=DOMに変更があった場合、取得したDOMも変更される。
つまり、HTMLCollectionは
現在の状態のDOM内の要素をリスト化している
要素の取得方法まとめ https://qiita.com/amamamaou/items/25e8b4e1b41c8d3211f4#htmlcollection-%E3%81%A8-nodelist-%E3%81%AE%E9%81%95%E3%81%84
つまり、HTMLCollectionはDOMの状態に依存するけれども、NodeListは取得したらそのままそれで決まり!という違いがあるということです。
知らなかった。
まとめ
今回は、【JavaScript】NodeListとかいうやつを配列に置き換えると、JSと仲良くなれそう、というテーマで解説してきました。
JS、もっとズブズブの友達になりたい…
このブログは、月に15本を目標に、実務から学んだプログラミングのあれこれを発信しています。
誰かのためになれば、嬉しいです。
最後まで読んでいただき、ありがとうございました。
それでは。