JavaScript

動的に増えるフォームで沼る理由。NodeListではなく、HTMLCollectionを利用しよう(実例つき)。

バートリーのさいとうです。

今回は

動的に増えるフォームで沼る理由。NodeListではなく、HTMLCollectionを利用しよう。

というテーマで、普段の業務から得られた学びを共有していきます。

今回は、アプリケーションのフォームから登録する処理を実装する際に、以下のような悩みを抱えている人向けの記事となります。

  • emailのドメイン部に大文字が含まれている(iCloudみたいな)場合は自動置換したい。
  • カタカナ入力を求めているフィールドでカタカナ以外が入力される
  • 可能なら、フロント側でバリデーションなどをかけたい。
  • しかも、動的なフォームで実装したい

動的に増えるフォームというのは、例えば以下のような状況です。

フォームを追加するを押下すると、フォームが追加されます。

See the Pen 動的に増えるフォームで沼る理由 by バートリーのさいとう@エンジニア (@bartleysaito) on CodePen.

そんな時、NodeListとHTMLCollectionの違いを理解しておかないと、ちょっと沼にハマりやすくなってしまうんです。

この記事を読めば

この記事を読むメリット
  • JavaScriptで複数の要素を取得する際に気をつけるべき三つの型を理解することができる
  • NodeLIstとHTMLCollectionの違いを理解し、使い分けられるようになる
  • 動的と静的の違いがわかる
  • 動的なフォームでは、HTMLCollectionを利用するべき理由がわかる
  • 動的なフォームのそれぞれに対してバリデーションがかけられるようになる

と思いますので、是非最後までお付き合いください。

JavaScriptで複数要素を取得する際の3つの型

前提として、JavaScript(以下JS)を利用した複数要素の取得方法から。
ここを抑えておくと、後の内容も理解がしやすくなるかと思います。

JSでは、以下の3つの形で複数要素を取得・加工することが可能です。

  • NodeList
  • HTMLCollection
  • Array(配列)

大きな括りで分けられるのは

NodeList
HTMLCollection

Array

です。

違いは、配列用のメソッドを利用できるか否かです。

NodeListHTMLCollection は .length で要素数を取得したりはできるのですが、配列ではないので map とか some のような配列のメソッドが使えない場合があります。

JavaScript NodeList, HTMLCollection は配列(Array)ではない

とあるように、Arrayクラスから生成されたオブジェクトであれば、こちらのページで確認できるメソッドは利用可能だが、NodeListとHTMLCollectionでは利用できないということです。

つまり、Arrayは配列NodeListとHTMLCollectionは配列”風“なオブジェクトということができます。

では次に、本題である「NodeListとHTMLCollectionの違いは何か?」を見ていきましょう。

NodeListとHTMLCollectionの違い

ここまでで、NodeListとHTMLCollectionが配列”風”なオブジェクトであることがわかりました。

まず、両者に共通するのは、HTMLの要素を複数取得する際の型、です。

例えば

//HTMLCollection
document.getElementsByClassName("class名")

//NodeList
document.getElementsByName("name属性")
document.querySelectorAll(class名)

のような形でhtmlから要素を取得することができます。

一方で、この両者の違いは

  • NodeList = 静的に要素を取得
  • HTMLCollection = 動的に要素を取得

です。これらは何が違うのでしょう?

動的と静的とは?

動的とは

変わる」

静的とは

「変わらない」

です。

例えば、ユーザーがフォームを増やせる場合は、変わっているか変わっていないかでいうと…

変わっていますよね。

逆に、「フォームを追加する」ボタンがない場合は変わらないです。

このように、変わる(可能性がある)場合は動的に要素を取得したいのでHTMLCollectionを利用します。

変わらない場合は、基本的にどちらでも問題ないですが、HTMLCollectionではループ用のforEachが使えなかったりとメソッドの制限があるので、注意が必要です。

HTMLCollectionで動的なフォームに対応する(実例)

ここまでをまとめると、動的に増えるフォームに対して処理を行いたいときは、HTMLCollectionで要素を取得しないと、増えた分のフォームに対して処理ができないということになります。

では、最後に実例をお見せして終わりにしたいと思います。

要件としては

  • E-mailフォームに@が含まれていないとアラートが出る
  • フォームを追加して、2つ目以降のemailフォームの入力が正しくない場合でも、「n番目のメールアドレスのフォーマットが正しくありません。」と出力できる

です。

emailのフォームに@抜きの値を入れて、フォームからフォーカスを外すと、アラートが出るので試してみてください。

See the Pen Untitled by バートリーのさいとう@エンジニア (@bartleysaito) on CodePen.

余談ですが、submitでエラーを出すより、onblurでアラートを出した方が、ユーザビリティ高いなと思うのは僕だけですかね。(わからん)

まとめ

いかがだったでしょうか。

今回は、動的に増えるフォームで沼る理由。NodeListではなく、HTMLCollectionを利用しよう。というテーマで解説しました。

このブログは、月に15本を目標に、実務から学んだプログラミングのあれこれを発信しています。

誰かのためになれば、嬉しいです。

最後まで読んでいただき、ありがとうございました。

それでは。

参考資料

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA