JavaScript の querySelector メソッドと getElementById メソッドの違いを分析する

JavaScript の querySelector メソッドと getElementById メソッドの違いを分析する

1. 概要

コードを見ていると、基本的にquerySelector()とquerySelectorAll()を使って要素を取得しているのに、なぜgetElementById()が使われていないのか疑問に思いました。
おそらくその2つを使ったことがないので理由はわかりません。

1.1 querySelector() と querySelectorAll() の使用

querySelector() メソッド

定義: querySelector() メソッドは、指定された CSS セレクターに一致するドキュメント内の要素を返します。
注: querySelector() メソッドは、指定されたセレクターに一致する最初の要素のみを返します。すべての要素を返す必要がある場合は、代わりに querySelectorAll() メソッドを使用してください。
構文: document.querySelector(CSS セレクター);
パラメータ値: 文字列必須。一致する要素に対して 1 つ以上の CSS セレクターを指定します。 ID、クラス、タイプ、属性、属性値などを使用して要素を選択します。
セレクターが複数ある場合は、それらをコンマで区切り、一致する要素を 1 つ返します。
戻り値: 指定された CSS セレクターに一致する最初の要素。 見つからない場合は null を返します。無効なセレクターが指定された場合、SYNTAX_ERR 例外がスローされます。

querySelectorAll() メソッド

定義: querySelectorAll() メソッドは、指定された CSS セレクターに一致するドキュメント内のすべての要素を返し、NodeList オブジェクトを返します。
NodeList オブジェクトはノードのコレクションを表します。インデックスでアクセスできます。インデックス値は 0 から始まります。
ヒント: NodeList オブジェクトの長さプロパティを使用してセレクターに一致する要素属性を取得し、すべての要素を反復処理して必要な情報を取得できます。
構文: elementList = document.querySelectorAll(selectors);
elementList は NodeList 型の静的オブジェクトです。
セレクターは、コンマで区切られた 1 つ以上の CSS セレクターを含む文字列です。
パラメータ値: 文字列必須。 CSS セレクターに一致する 1 つ以上の要素を指定します。要素を取得するためのセレクターとして、ID、クラス、タイプ、属性、属性値などを使用できます。
複数のセレクターを区切るには、カンマ (,) を使用します。
戻り値: 指定された CSS セレクターに一致するドキュメント内のすべての要素を表す NodeList オブジェクト。
NodeList は、NodeList 型の静的オブジェクトです。指定されたセレクターが無効な場合、SYNTAX_ERR 例外がスローされます。

1.2 getElement(s)Byxxxx の使用

getElementById() メソッド

定義: getElementById() メソッドは、指定された ID を持つ最初のオブジェクトへの参照を返します。
指定された ID を持つ要素が存在しない場合は null を返します。
指定された ID を持つ要素が複数ある場合は、最初の要素が返されます。
ID を持たない要素を見つける必要がある場合は、CSS セレクターで querySelector() を使用することを検討してください。
構文: document.getElementById(elementID);
パラメータ値: 文字列必須。要素 ID 属性値。
戻り値: 要素オブジェクト 指定されたIDを持つ要素

getElementsByTagName() メソッド

定義: getElementsByTagName() メソッドは、指定されたタグ名を持つオブジェクトのコレクションを返します。
ヒント: パラメータ値「*」はドキュメントのすべての要素を返します。
構文: document.getElementsByTagName(タグ名)
パラメータ: 文字列 (必須) 取得する要素のタグ名。
戻り値: NodeList オブジェクト、指定されたタグ名を持つ要素のコレクション

getElementsByClassName() メソッド

定義: getElementsByClassName() メソッドは、ドキュメント内の指定されたクラス名を持つすべての要素のコレクションを NodeList オブジェクトとして返します。
NodeList オブジェクトは、順序付けられたノードのリストを表します。 NodeList オブジェクトは、ノード リスト内のノード インデックス番号 (インデックス番号は 0 から始まります) を通じてテーブル内のノードにアクセスできます。
ヒント: NodeList オブジェクトの長さプロパティを使用して、指定されたクラス名の要素の数を判別し、各要素をループして必要な要素を取得できます。
構文: document.getElementsByClassName(classname)
パラメータ: 文字列 取得する要素のクラス名。 複数のクラス名はスペースで区切られます (例: "test demo")。
戻り値: 指定されたクラス名の要素コレクションを表す NodeList オブジェクト。コレクション内の要素の順序は、コード内に表示される順序になります。

2. 違い

2.1 getElement(s)Byxxxx は動的コレクションを取得し、querySelector は静的コレクションを取得します。

動的とは、選択した要素がドキュメントとともに変更されることを意味し、静的とは、要素が取り出された後にドキュメントの変更とは関係がないことを意味します。

例1:

<本文>
  <ul id="box">
    <li class="a">テスト 1</li>
    <li class="a">テスト 2</li>
    <li class="a">テスト 3</li>
  </ul>
</本文>

<script type="text/javascript">
  // ul を取得し、後で li を動的に追加します
  var ul = document.getElementById('box');
  //既存の ul 内の li を取得します
  var リスト = ul.getElementsByTagName('li');
  for(var i =0; i < list.length; i++){
    ul.appendChild(document.createElement('li')); // liを動的に追加
  }
</スクリプト>

上記のコードは、i < list.length というループ条件で無限ループに陥ります。
初めて 3 つの li を取得した後は、ul に新しい要素が追加されるたびに、リストの値が更新され、ul 内のすべての li が再取得されるからです。
つまり、getElement(s)Byxxxx は、DOM 構造の変更に応じて常に変化する動的なコレクションを取得します。
つまり、リストを呼び出すたびにドキュメントが再クエリされ、無限ループの問題が発生します。

例1の変更:

for ループ条件を i < 4 に変更します。その結果、ul に 4 つの新しい要素が追加され、挿入される li タグの数は 7 になります。

<本文>
  <ul id="box">
    <li class="a">テスト 1</li>
    <li class="a">テスト 2</li>
    <li class="a">テスト 3</li>
  </ul>
</本文>

<script type="text/javascript">
  var ul = document.getElementById('box');

  var リスト = ul.getElementsByTagName('li');
  (var i = 0; i < 4; i++){
    ul.appendChild(document.createElement('li'));
  }
  console.log('リストの長さ:',リストの長さ);
</スクリプト> 

ここに画像の説明を挿入

例2:

次のコードの静的コレクションは、ul 内のすべての li を取得した後、.querySelectorAll('li') に反映されます。後で動的に li がいくつ追加されても、そのパラメータには影響しません。

<本文>
  <ul id="box">
    <li class="a">テスト 1</li>
    <li class="a">テスト 2</li>
    <li class="a">テスト 3</li>
  </ul>
</本文>

<script type="text/javascript">
  var ul = document.querySelector('ul');

  var リスト = ul.querySelectorAll('li');
  for(var i = 0; i < list.length; i++){
    ul.appendChild(document.createElement('li'));
  }
  console.log('list.length:',list.length); //出力結果は3のままで、この時点でのliの数は6ではありません
</スクリプト> 

ここに画像の説明を挿入

なぜこのように設計されているのでしょうか?
querySelectorAll メソッドは、W3C 仕様で明確に定義されています。

querySelectorAll() メソッドによって返される NodeList オブジェクトは静的である必要があります ([DOM]、セクション 8)。

Chrome で何が起こるか見てみましょう:

document.querySelectorAll('a').toString(); // "[object NodeList]" を返す
document.getElementsByTagName('a').toString(); // "[object HTMLCollection]" を返します

HTMLCollection は W3C で次のように定義されています。

HTMLCollection はノードのリストです。個々のノードには、序数インデックス、ノードの名前または ID 属性のいずれかでアクセスできます。注: HTML DOM 内のコレクションはライブであると想定されており、基礎となるドキュメントが変更されると自動的に更新されます。

実際、HTMLCollection と NodeList は非常によく似ています。どちらも要素の動的なコレクションであり、アクセスするたびにドキュメントの再クエリが必要になります。
違い: HTMLCollection は Document Object Model HTML 仕様に属しますが、NodeList は Document Object Model Core 仕様に属します。
これは少し理解しにくいですが、次の例を見ると理解しやすくなります。

var ul = document.getElementsByTagName('ul')[0],
    lis1 = ul.childNodes、
    lis2 = ul.children;
console.log(lis1.toString(), lis1.length); // "[オブジェクト NodeList]" 11
console.log(lis2.toString(), lis2.length); // "[オブジェクト HTMLCollection]" 4

NodeList オブジェクトには、要素、テキスト、コメントなど、ドキュメント内のすべてのノードが含まれます。
HTMLCollection オブジェクトには、ドキュメント内の Element ノードのみが含まれます。
さらに、HTMLCollection オブジェクトは、NodeList オブジェクトよりも 1 つ多い namedItem メソッドを提供します。
したがって、ブラウザでは、querySelectorAll の戻り値は静的な NodeList オブジェクトですが、getElementsBy シリーズの戻り値は実際には HTMLCollection オブジェクトになります。

2.2 受信したパラメータが異なる

querySelectorAll メソッドによって受け取られるパラメータは CSS セレクターです。
getElementsBy シリーズが受け取るパラメータは、className、tagName、name の 1 つだけです。

var c1 = document.querySelectorAll('.b1 .c');
var c2 = document.getElementsByClassName('c');
var c3 = document.getElementsByClassName('b2')[0].getElementsByClassName('c');

注: querySelectorAll が受け取るパラメータは、CSS セレクタ仕様に厳密に準拠している必要があります。<br /> 次の記述は例外をスローします (CSS セレクタ内の要素名、クラス、ID は数字で始めることはできません)。

試す {
  var e1 = document.getElementsByClassName('1a2b3c');
  var e2 = document.querySelectorAll('.1a2b3c');
} キャッチ (e) {
  コンソールエラー(e.message);
}
コンソールにログ出力します。(e1 && e1[0].className);
コンソールにログ出力します。(e2 && e2[0].className);

2.3 異なるブラウザの互換性

querySelectorAll は、IE 8 以降、FF 3.5 以降、Safari 3.1 以降、Chrome、Opera 10 以降でサポートされています。
getElementsBy シリーズは、最新の仕様に追加された getElementsByClassName を例にとると、すでに IE 9+、FF 3+​​、Safari 3.1+、Chrome、Opera 9+ でサポートされています。

2.4 querySelectorはW3CのSelectors API仕様に属し、getElementsByシリーズはW3CのDOM仕様に属します。

参考記事(侵害の場合は削除)

JavaScript の querySelector メソッドと getElementById メソッドの違いについての記事はこれで終わりです。js の querySelector メソッドと getElementById メソッドの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JS の querySelector メソッドと getElementById メソッドの違い
  • js querySelector() の使用法
  • ID で要素を取得する場合の js querySelector と getElementById の違い
  • JavaScript の querySelector と querySelectorAll の紹介
  • javascript typeof id===''string''?document.getElementById(id):id の説明
  • ネイティブ js チェックボックス操作は document.getElementById を使用して実装されます。
  • getElementByIdx_x js カスタム getElementById 関数
  • javascript getElementById の使い方と使用方法

<<:  純粋な CSS ヘッダーの実装コードを修正

>>:  Docker クリーニングの一般的な方法と問題点

推薦する

MySQL でデータの重複挿入を回避する 4 つの方法

最も一般的な方法は、フィールドに主キーまたは一意のインデックスを設定することです。重複データを挿入す...

React antdはフォームの動的な増減を実現します

以前、動的フォームを記述しているときに落とし穴に遭遇しました。インデックスの添え字をキーとして使用す...

Linux 上の Vim で色とテーマを変更する方法

Vim は Linux でよく使用されるテキスト エディターです。 Vim は、Sublime や ...

MySQL 5.7.18 MSI インストール グラフィック チュートリアル

この記事では、参考までにMySQL 5.7.18 MSIインストールチュートリアルを紹介します。具体...

HTML テーブルの境界線を設定する際のヒント

HTML を初めて使用する多くの人にとって、テーブル <table> は最もよく使用され...

SQLクエリの実行順序をゼロから学ぶ

SQL クエリ ステートメントの実行順序は次のとおりです。 (7)選択 (8) DISTINCT &...

MySQL 5.7.17 のインストールと設定方法のグラフィック チュートリアル (Windows)

1. ソフトウェアをダウンロードする1. MySQL の公式サイトにアクセスし、Oracle アカ...

2列の水平タイムラインを実装するためのVueサンプルコード

目次1.コンポーネントtimelineH.vueを実装する2. コンポーネントの呼び出しこの記事では...

JS+Canvas が抽選ホイールを引く

この記事では、宝くじターンテーブルを描画するJS + Canvasの具体的なコードを参考までに共有し...

MYSQL ロック解除とロックテーブルの紹介

MySQL ロックの概要他のデータベースと比較すると、MySQL のロック メカニズムは比較的単純で...

MySql データベースにリモートでログインするにはどうすればよいですか?

はじめに: プロジェクトを開発するために、サーバーに MySql データベース サーバーを展開し、ロ...

vue3 タイムスタンプ変換 (フィルターを使用せずに)

vue2 では、タイムスタンプを変換するときに、通常はフィルターを使用します。vue3 以降では、...

Vueはタブルーティング切り替えコンポーネントのメソッド例を実装します

序文この記事では、vue に付属している vue-router.js ルーティングを使用してページン...

Vue はグラフィック検証コードログインを実装します

この記事では、グラフィック認証コードログインを実装するためのVueの具体的なコードを参考までに紹介し...

LinuxにComposerをインストールする方法

1. インストールスクリプト(composer-setup.php)を現在のディレクトリにダウンロー...