JavaScript における querySelector と querySelectorAll、getElementsByClassName と getElementById の違い
P粉442576165
P粉442576165 2023-08-21 21:45:39
0
2
548

querySelectorquerySelectorAllgetElementsByClassNamegetElementById

このリンクから、querySelector を使用すると、document.querySelector(".myclass") を記述してクラス名<のファイルを取得できることがわかりました。 ;code>myclass、および document.querySelector("#myid")を使用して、ID myidを持つ要素を取得します。ただし、getElementsByClassNamegetElementById を使用すると、この機能はすでに実現できます。どちらを優先すべきでしょうか?

また、私は XPages で作業していますが、ID は動的に生成され、コロンが含まれており、この view:_id1:inputText1 のようになります。そのため、document.querySelector("#view:_id1:inputText1") と記述すると、機能しません。しかし、document.getElementById("view:_id1:inputText1") を書くと、それは機能します。なぜこれが起こっているのか何か考えはありますか?

P粉442576165
P粉442576165

全員に返信 (2)
P粉008829791

この回答では、querySelectorおよびquerySelectorAllを querySelector* と呼び、getElementByIdgetElementsByClassNamegetElementsByTagName とします。getElementsByNameは getElement* と呼ばれます。

この情報の多くは仕様で確認でき、その多くは私が執筆中に実行したさまざまなベンチマークから得られました。仕様:https://dom.spec.whatwg.org/

主な違い

  1. querySelector* は、単純な ID、タグ、クラスだけでなく、任意の CSS3 セレクターを渡すことができるため、より柔軟です。
  2. querySelector* のパフォーマンスは、呼び出される DOM のサイズによって異なります。正確に言うと、querySelector* の呼び出しは O(n) 時間で実行されますが、getElement* の呼び出しは O(1) 時間で実行されます。ここで、n は呼び出しが行われる要素またはドキュメントのすべての子要素の合計数です。
  3. これらの呼び出しの戻り値の型は異なります。querySelectorgetElementByIdは両方とも 1 つの要素を返します。querySelectorAllgetElementsByNameはどちらも NodeList を返します。getElementsByClassNamegetElementsByTagNameはどちらも HTMLCollection を返します。 NodeList と HTMLCollection はどちらも要素のコレクションと呼ばれます。
  4. コレクションはそれぞれ「ライブ」または「静的」コレクションを返すことができます。これは、返される実際の型には反映されません。 getElements* 呼び出しはライブ コレクションを返しますが、querySelectorAll は静的コレクションを返します。私の理解では、ライブ コレクションには DOM 内の要素への参照が含まれ、静的コレクションには要素のコピーが含まれます。別の視点については、以下の @Jan Feldmann のコメントをチェックすることもできます。これを回答に組み込む良い方法は見つかりませんでしたが、より正確に理解できるかもしれません。

これらの概念を以下の表にまとめます。

リーリー

詳細、ヒント、例

  • HTMLCollection は NodeList ほど配列らしくなく、.forEach() をサポートしません。この問題を回避するにはスプレッド演算子が役立つことがわかりました:

    [...document.getElementsByClassName("someClass")].forEach()

  • これらの関数はすべて、要素ごとに、またグローバルにdocumentからアクセスできます。ただし、getElementByIdgetElementsByNameは例外で、document# でのみ利用可能です。 ## に実装されています。

  • querySelector* の代わりに getElement* 呼び出しを連鎖させると、特に非常に大規模な DOM でのパフォーマンスが向上します。通常、小さな DOM や非常に長いチェーンでも高速になります。ただし、パフォーマンスが必要であることがわかっている場合を除き、querySelector* の読みやすさを読みやすさよりも優先する必要があります。

    querySelectorAllは、各ステップで NodeList または HTMLCollection から要素を選択する必要があるため、通常はオーバーライドが困難です。たとえば、次のコードは機能しません:

    document.getElementsByClassName("someClass").getElementsByTagName("div")

    getElements* はコレクションではなく単一の要素に対してのみ使用できるため、要素が 1 つだけ必要な場合は次のようになります。

    document.querySelector("#someId .someClass div")

    は次のように記述できます:

    document.getElementById("someId").getElementsByClassName("someClass")[0].getElementsByTagName("div")[0]

    [0]

    は、コレクションを返す各ステップで使用され、コレクションの最初の要素を取得することに注意してください。最終結果は、querySelectorを使用した場合と同様に、1 つの要素のみです。 。

  • すべての要素は querySelector* と getElement* を使用して呼び出すことができるため、両方の呼び出しを使用して操作を連鎖させることができます。これは、パフォーマンスを向上させたいが、実行できない getElement* 呼び出しの使用を避けられない場合に便利です。 querySelector の場合に非常に便利です。

  • 通常、getElement* 呼び出しのみを使用してセレクターを作成できるかどうかを判断するのは簡単ですが、明確ではない場合がある状況が 1 つあります。

    document.querySelectorAll(".class1.class2")

    に書き換えることができます

    document.getElementsByClassName("クラス1 クラス2")

  • querySelector* で取得した静的要素で getElement* を使用すると、要素は querySelector によってコピーされた静的 DOM サブセットに対して動的になりますが、完全なドキュメント DOM に対しては静的になります...これは簡単です。これは次のとおりです。ここで、動的/静的要素の解釈が崩れ始めます。これについて心配する必要がある状況は避けるようにしてください。ただし、このような状況が存在する場合は、querySelector* 呼び出しは参照を返す前に見つかった要素をコピーするのに対し、getElement* 呼び出しはコピーせずに参照を直接取得することに注意してください。

  • querySelector* および

    getElementByIdは、仕様では「ツリー順序」と呼ばれる、事前順序、深さ優先の方法で要素を走査します。他の getElement* 呼び出しについては、同じツリー順序にあるかどうかは仕様からはわかりませんが、getElementsByClassName(".someClass")[0]はすべてのブラウザーで確実に結果が得られるわけではありません。getElementById("#someId")は、ページ上に同じ ID のコピーが複数ある場合でも信頼できるはずです。

  • 無限スクロール ページに取り組んでいたときにこの問題を調査する必要があり、これはパフォーマンスが問題になる一般的な状況ではないかと思いました。コードには、querySelectorAll 呼び出しを含む onScroll イベントがあります。呼び出しのレートが制限されている場合でも、十分にスクロールするとページがクラッシュします。その時点で、多すぎる要素を反復する呼び出しが多すぎて、ブラウザーが追いつけなくなります。このユースケースでは DOM のサイズが関係するため、無限スクロール ページで実行されるコードでは getElement* 呼び出しが優先されます。

いいねを押す+0
    P粉238355860

    構文とブラウザのサポート。

    querySelectorは、より複雑なセレクターを使用する場合に便利です。

    たとえば、クラス foo に属するすべての要素のリスト:.foo li

    :文字はセレクター内で特別な意味を持ちます。それから逃れる必要があります。 (セレクターのエスケープ文字も JS 文字列では特別な意味を持つため、同様にをエスケープする必要があります)。リーリー

    いいねを押す+0
      最新のダウンロード
      詳細>
      ウェブエフェクト
      公式サイト
      サイト素材
      フロントエンドテンプレート
      私たちについて 免責事項 Sitemap
      PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!